Skip to content

Instantly share code, notes, and snippets.

@yoshihiro503
Last active July 1, 2022 10:18
Show Gist options
  • Save yoshihiro503/99540c6fcdb26b45eab0ee7f0e8e4c3b to your computer and use it in GitHub Desktop.
Save yoshihiro503/99540c6fcdb26b45eab0ee7f0e8e4c3b to your computer and use it in GitHub Desktop.
open SCaml
let empty_bytes = Bytes "0x"
let is_empty_bytes b = (Bytes.length b = Nat 0)
let bytes_concat sep ss =
match ss with
| [] -> empty_bytes
| s0 :: ss ->
List.fold_left' (fun (acc, s) -> Bytes.concat (Bytes.concat acc sep) s) s0 ss
type encoded_segment = bytes
let encode_segment (seg : encoded_segment) : bytes = seg
module Hash = struct
type prefix = bytes
let prefix_to_bytes p : bytes = p
type t = (prefix * bytes)
let of_prefix p : t = (p, empty_bytes)
let zero : t = of_prefix (Bytes "0x00000000000000000000000000000000")
let of_bytes b : prefix = Crypto.blake2b b
let of_list ss : prefix = of_bytes (bytes_concat empty_bytes ss)
let to_bytes_list : t -> bytes list = function
| (p, b) when is_empty_bytes b -> [prefix_to_bytes p]
| (p, b) -> [prefix_to_bytes p; b]
let combine_flags (p: prefix) (flags:nat) : prefix =
p
let to_prefix : t -> prefix = fst
let make prefix b : t = (prefix, b)
(* let to_string ((prefix, b): t) =*)
(* Bytes.to_string prefix ^ "-" ^ Bytes.to_string b*)
end
type hash = Hash.t
let hash_of_bud : hash option -> hash = function
| None -> Hash.zero
| Some h ->
let p = Hash.of_list (Hash.to_bytes_list h) in
let p = Hash.combine_flags p (Nat 0b11) in
Hash.of_prefix p
let hash_of_leaf (v: bytes) : hash =
Hash.of_prefix (Hash.of_bytes v)
let hash_of_internal (h1: hash) (h2 : hash) =
let p = Hash.of_list [Hash.to_prefix h1; Hash.to_prefix h2] in
Hash.of_prefix p
let hash_of_extender (seg: encoded_segment) (h : hash) =
Hash.make (Hash.to_prefix h) (encode_segment seg)
type node_key = nat
type node_ref =
| Hash of hash
| Bud of node_key option
| Leaf of bytes
| Internal of node_key * node_key
| Extender of encoded_segment * node_key
type node = {root_key : node_key; elems: (node_key * node_ref) list}
type hash_cache = (node_key, hash) Map.t
let compute_hash node =
let hashes = List.fold_left'
(fun (cache, (node_key, node_ref)) ->
let h =
match node_ref with
| Hash h -> Some h
| Bud None ->
Some (hash_of_bud None)
| Bud (Some n) ->
begin match Map.get n cache with
| None -> None
| Some h -> Some (hash_of_bud (Some h))
end
| Leaf v -> Some (hash_of_leaf v)
| Internal (l, r) ->
begin match Map.get l cache, Map.get r cache with
| Some h1, Some h2 ->
Some (hash_of_internal h1 h2)
| _, _ -> None
end
| Extender (seg, n) ->
begin match Map.get n cache with
| None -> None
| Some h ->
Some (hash_of_extender seg h)
end
in
match h with
| None ->
failwith "compute_hash"
| Some h ->
Map.update node_key (Some h) cache)
Map.empty
node.elems
in
Map.get node.root_key hashes
type proof = node
type storage = NoStorage
type segment_elem = L | R | Seg of encoded_segment
type segment = segment_elem list
type path = segment list
let find_child node_map segment node_key =
let f = function
| (None, _) -> None
| (Some (Internal (l, _)), L) ->
Map.get l node_map
| (Some (Internal (_, r)), R) ->
Map.get r node_map
| (Some (Extender (eseg, n)), Seg s) when (eseg = s) ->
Map.get n node_map
| (Some _, _) -> None
in
let top = Map.get node_key node_map in
List.fold_left' f top segment
let map_of_assoc (list : (node_key * node_ref) list) =
List.fold_left' (fun (map, (key,value)) -> Map.update key (Some value) map) Map.empty list
let find path proof =
let node_map = map_of_assoc proof.elems in
let root = Map.get proof.root_key node_map in
let leaf_opt =
List.fold_left' (function
| (None, _) -> None
| (Some (Bud (Some n)), segment) ->
find_child node_map segment n
| (Some _, _) -> None)
root
path
in
match leaf_opt with
| None -> None
| Some (Leaf v) -> Some v
| Some _ -> None
type param = {
proof: proof;
expected_root_hash : hash;
data: (path * bytes) list;
}
let is_proof_valid expected_root_hash proof =
match compute_hash proof with
| Some h ->
(expected_root_hash = h)
| None ->
false
let check_data proof data =
let check proof (path, v_expected) =
match find path proof with
| None -> false
| Some v -> v_expected = v
in
List.fold_left' (fun (acc, path) -> acc && check proof path) true data
let [@entry] verify param NoStorage =
if is_proof_valid param.expected_root_hash param.proof = false then
failwith "is_proof_valid"
else if check_data param.proof param.data = false then
failwith "check data"
else
([], NoStorage)
@yoshihiro503
Copy link
Author

scamlc verify_plebeia_merkle_proof.ml
Constructor compilation failure: Ok
Fatal error: exception File "src/translate.ml", line 735, characters 6-12: Assertion failed
Raised at SCamlc__Translate.construct in file "src/translate.ml", line 735, characters 6-18
Called from SCamlc__Translate.expression in file "src/translate.ml", line 891, characters 41-79
Called from SCamlc__Translate.expression.compile_case in file "src/translate.ml", line 1145, characters 46-72
Called from Stdlib__list.rev_map.rmap_f in file "list.ml", line 103, characters 22-25
Called from Spotlib__Xlist.map in file "lib/xlist.ml" (inlined), line 146, characters 21-32
Called from SCamlc__Translate.expression in file "src/translate.ml", line 1147, characters 35-64
Called from SCamlc__Translate.expression.(fun) in file "src/translate.ml", line 926, characters 26-49
Called from Spotlib__Xlist.fold_right.aux in file "lib/xlist.ml", line 172, characters 19-27
Called from SCamlc__Translate.expression in file "src/translate.ml", line 923, characters 8-695
Called from SCamlc__Translate.expression.compile_case in file "src/translate.ml", line 1116, characters 37-63
Called from Stdlib__list.rev_map.rmap_f in file "list.ml", line 103, characters 22-25
Called from Spotlib__Xlist.map in file "lib/xlist.ml" (inlined), line 146, characters 21-32
Called from SCamlc__Translate.expression in file "src/translate.ml", line 1118, characters 48-75
Called from Stdlib__list.rev_map.rmap_f in file "list.ml", line 103, characters 22-25
Called from Spotlib__Xlist.map in file "lib/xlist.ml" (inlined), line 146, characters 21-32
Called from SCamlc__Translate.expression in file "src/translate.ml" (inlined), line 974, characters 10-165
Called from SCamlc__Translate.expression in file "src/translate.ml", line 1083, characters 50-63
Called from SCamlc__Translate.expression.(fun) in file "src/translate.ml", line 926, characters 26-49
Called from Spotlib__Xlist.fold_right.aux in file "lib/xlist.ml", line 172, characters 19-27
Called from SCamlc__Translate.expression in file "src/translate.ml", line 923, characters 8-695
Called from SCamlc__Translate.expression.compile_case in file "src/translate.ml", line 1116, characters 37-63
Called from Stdlib__list.rev_map.rmap_f in file "list.ml", line 103, characters 22-25
Called from Spotlib__Xlist.map in file "lib/xlist.ml" (inlined), line 146, characters 21-32
Called from SCamlc__Translate.expression in file "src/translate.ml", line 1118, characters 48-75
Called from SCamlc__Translate.value_binding in file "src/translate.ml", line 1330, characters 10-33
Called from SCamlc__Translate.structure_item.(fun) in file "src/translate.ml", line 1360, characters 22-69
Called from Spotlib__Xlist.fold_right.aux in file "lib/xlist.ml", line 172, characters 19-27
Called from SCamlc__Translate.structure_item in file "src/translate.ml", line 1358, characters 8-189
Called from SCamlc__Translate.structure.(fun) in file "src/translate.ml", line 1414, characters 22-53
Called from Stdlib__list.fold_left in file "list.ml", line 121, characters 24-34
Called from SCamlc__Contract.translate_structure in file "src/contract.ml", line 484, characters 8-42
Called from SCamlc__Contract.implementation in file "src/contract.ml", line 789, characters 4-38
Called from SCaml_tools.with_time in file "src/tools/SCaml_tools.ml", line 112, characters 12-16
Called from SCamlc__SCamlComp.translate_and_optimize.(fun) in file "src/SCamlComp.ml", line 156, characters 4-92
Called from SCamlc__Conf.with_opt in file "src/conf.ml", line 187, characters 12-16
Called from SCamlc__SCamlComp.compile.(fun) in file "src/SCamlComp.ml", line 323, characters 16-46
Called from Dune__exe__Main.Compile_common.implementation.(fun) in file "driver/main.ml", line 155, characters 15-33
Called from Misc.try_finally in file "utils/misc.ml", line 31, characters 8-15
Re-raised at Misc.try_finally in file "utils/misc.ml", line 45, characters 10-56
Called from Misc.try_finally in file "utils/misc.ml", line 31, characters 8-15
Re-raised at Misc.try_finally in file "utils/misc.ml", line 45, characters 10-56
Called from Misc.try_finally in file "utils/misc.ml", line 31, characters 8-15
Re-raised at Misc.try_finally in file "utils/misc.ml", line 45, characters 10-56
Called from Compenv.process_action.impl in file "driver/compenv.ml", line 624, characters 4-69
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Compenv.process_deferred_actions in file "driver/compenv.ml", line 708, characters 2-61
Called from Dune__exe__Main.Maindriver.main.(fun) in file "driver/main.ml", line 284, characters 6-147
Called from SCamlc__Conf.with_opt in file "src/conf.ml", line 187, characters 12-16
Called from Dune__exe__Main.Maindriver.main in file "driver/main.ml", line 275, characters 4-1023
Re-raised at Location.report_exception.loop in file "parsing/location.ml", line 926, characters 14-25
Called from Dune__exe__Main.Maindriver.main in file "driver/main.ml", line 343, characters 4-35
Called from Dune__exe__Main.Main in file "driver/main.ml", line 352, characters 7-54

@yoshihiro503
Copy link
Author

↑上記のコンパイルエラーはStdlibのresult型を使っていたからのようだ。
ScamlではStdlibは使わず、SCaml.mliのAPIだけを使うようにすべしということで修正した。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment