From 9e8ff1470b643eb2bd7090c058285105e10bb136 Mon Sep 17 00:00:00 2001 From: sai Date: Mon, 2 Sep 2024 16:42:24 -0400 Subject: [PATCH 1/4] snarked_ledger membership refactor --- src/lib/mina_graphql/mina_graphql.ml | 125 ++++++++++++++++++--------- src/lib/mina_graphql/types.ml | 7 ++ 2 files changed, 91 insertions(+), 41 deletions(-) diff --git a/src/lib/mina_graphql/mina_graphql.ml b/src/lib/mina_graphql/mina_graphql.ml index 0783e1351a8..c3ca5d0bc71 100644 --- a/src/lib/mina_graphql/mina_graphql.ml +++ b/src/lib/mina_graphql/mina_graphql.ml @@ -2192,8 +2192,68 @@ module Queries = struct let (module S) = Mina_lib.work_selection_method mina in S.pending_work_statements ~snark_pool ~fee_opt snark_job_state ) - let snarked_ledger_account_membership = - io_field "snarkedLedgerAccountMembership" + module SnarkedLedgerMembership = struct + let resolve_membership : + mapper:(Ledger.path -> Account.t -> 'a) + -> Mina_lib.t resolve_info + -> unit + -> (Account.key * Token_id.t option) list + -> string + -> ('a list, string) result Io.t = + fun ~mapper { ctx = mina; _ } () account_infos state_hash -> + let open Deferred.Let_syntax in + let state_hash = State_hash.of_base58_check_exn state_hash in + let%bind ledger = + Mina_lib.get_snarked_ledger_full mina (Some state_hash) + in + let ledger = + match ledger with + | Ok ledger -> + ledger + | Error err -> + raise + (Failure + ("Failed to get snarked ledger: " ^ Error.to_string_hum err) ) + in + let%map memberships = + Deferred.List.map account_infos ~f:(fun (pk, token) -> + let token = Option.value ~default:Token_id.default token in + let account_id = Account_id.create pk token in + let location = Ledger.location_of_account ledger account_id in + match location with + | None -> + raise (Failure "Account not found in snarked ledger") + | Some location -> ( + let account = Ledger.get ledger location in + match account with + | None -> + raise (Failure "Account not found in snarked ledger") + | Some account -> + let proof = Ledger.merkle_path ledger location in + mapper proof account |> Deferred.return ) ) + in + Ok memberships + + let snarked_ledger_account_membership = + io_field "snarkedLedgerAccountMembership" + ~doc: + "obtain a membership proof for an account in the snarked ledger \ + along with the account's balance, timing information, and nonce" + ~args: + Arg. + [ arg "accountInfos" ~doc:"Token id of the account to check" + ~typ: + (non_null (list (non_null Types.Input.AccountInfo.arg_typ))) + ; arg "stateHash" ~doc:"Hash of the snarked ledger to check" + ~typ:(non_null string) + ] + ~typ:(non_null (list (non_null Types.SnarkedLedgerMembership.obj))) + ~resolve: + (resolve_membership ~mapper:Types.SnarkedLedgerMembership.of_account) + + (* + let encoded_snarked_ledger_accounts_membership = + io_field "encodedSnarkedLedgerAccountsMembership" ~doc: "obtain a membership proof for an account in the snarked ledger along \ with the account's balance, timing information, and nonce" @@ -2204,49 +2264,32 @@ module Queries = struct ; arg "stateHash" ~doc:"Hash of the snarked ledger to check" ~typ:(non_null string) ] - ~typ:(non_null (list (non_null Types.SnarkedLedgerMembership.obj))) - ~resolve:(fun { ctx = mina; _ } () account_infos state_hash -> + ~typ:(non_null string) + ~resolve:(fun resolve_info args account_infos state_hash -> let open Deferred.Let_syntax in - let state_hash = State_hash.of_base58_check_exn state_hash in - let%bind ledger = - Mina_lib.get_snarked_ledger_full mina (Some state_hash) + let%map memberships = + resolve_membership resolve_info () account_infos state_hash in - let ledger = - match ledger with - | Ok ledger -> - ledger + let memberships = + match memberships with + | Ok memberships -> + memberships | Error err -> - raise - (Failure - ("Failed to get snarked ledger: " ^ Error.to_string_hum err) - ) + raise (Failure err) in - let%map memberships = - Deferred.List.map account_infos ~f:(fun (pk, token) -> - let token = Option.value ~default:Token_id.default token in - let account_id = Account_id.create pk token in - let location = Ledger.location_of_account ledger account_id in - match location with - | None -> - raise (Failure "Account not found in snarked ledger") - | Some location -> ( - let account = Ledger.get ledger location in - match account with - | None -> - raise (Failure "Account not found in snarked ledger") - | Some account -> - let account_balance = account.balance in - let timing_info = account.timing in - let nonce = account.nonce in - let proof = Ledger.merkle_path ledger location in - { Types.SnarkedLedgerMembership.account_balance - ; timing_info - ; nonce - ; proof - } - |> Deferred.return ) ) + (* encode memberships to a base64 encoded string *) + let encoded_memberships = + let encoded_memberships = + List.map memberships ~f:(fun membership -> + Types.SnarkedLedgerMembership.to_yojson membership + |> Yojson.Safe.to_string ) + in + let encoded_memberships = String.concat ~sep:"\n" encoded_memberships in + Base64.encode_exn encoded_memberships in - Ok memberships ) + Ok encoded_memberships ) + *) + end let genesis_constants = field "genesisConstants" @@ -2733,7 +2776,7 @@ module Queries = struct ; trust_status_all ; snark_pool ; pending_snark_work - ; snarked_ledger_account_membership + ; SnarkedLedgerMembership.snarked_ledger_account_membership ; genesis_constants ; time_offset ; validate_payment diff --git a/src/lib/mina_graphql/types.ml b/src/lib/mina_graphql/types.ml index e027aa9632c..a831a0b93eb 100644 --- a/src/lib/mina_graphql/types.ml +++ b/src/lib/mina_graphql/types.ml @@ -779,6 +779,13 @@ module SnarkedLedgerMembership = struct ; proof : Ledger.path } + let of_account (proof : Ledger.path) (account : Account.t) : t = + { account_balance = account.balance + ; timing_info = account.timing + ; nonce = account.nonce + ; proof + } + let obj = obj "MembershipInfo" ~fields:(fun _ -> [ field "accountBalance" From ad15fd0af7865c3db1931762091ceb2d763df49b Mon Sep 17 00:00:00 2001 From: sai Date: Mon, 2 Sep 2024 17:05:58 -0400 Subject: [PATCH 2/4] Adding a type for encoded output --- src/lib/mina_graphql/mina_graphql.ml | 57 ++++++++++------------------ src/lib/mina_graphql/types.ml | 24 ++++++++++++ 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/lib/mina_graphql/mina_graphql.ml b/src/lib/mina_graphql/mina_graphql.ml index c3ca5d0bc71..83b9e043b87 100644 --- a/src/lib/mina_graphql/mina_graphql.ml +++ b/src/lib/mina_graphql/mina_graphql.ml @@ -2251,44 +2251,25 @@ module Queries = struct ~resolve: (resolve_membership ~mapper:Types.SnarkedLedgerMembership.of_account) - (* - let encoded_snarked_ledger_accounts_membership = - io_field "encodedSnarkedLedgerAccountsMembership" - ~doc: - "obtain a membership proof for an account in the snarked ledger along \ - with the account's balance, timing information, and nonce" - ~args: - Arg. - [ arg "accountInfos" ~doc:"Token id of the account to check" - ~typ:(non_null (list (non_null Types.Input.AccountInfo.arg_typ))) - ; arg "stateHash" ~doc:"Hash of the snarked ledger to check" - ~typ:(non_null string) - ] - ~typ:(non_null string) - ~resolve:(fun resolve_info args account_infos state_hash -> - let open Deferred.Let_syntax in - let%map memberships = - resolve_membership resolve_info () account_infos state_hash - in - let memberships = - match memberships with - | Ok memberships -> - memberships - | Error err -> - raise (Failure err) - in - (* encode memberships to a base64 encoded string *) - let encoded_memberships = - let encoded_memberships = - List.map memberships ~f:(fun membership -> - Types.SnarkedLedgerMembership.to_yojson membership - |> Yojson.Safe.to_string ) - in - let encoded_memberships = String.concat ~sep:"\n" encoded_memberships in - Base64.encode_exn encoded_memberships - in - Ok encoded_memberships ) - *) + let encoded_snarked_ledger_account_membership = + io_field "encodedSnarkedLedgerAccountMembership" + ~doc: + "obtain a membership proof for an account in the snarked ledger \ + along with the accounts full information encoded as base64 binable \ + type" + ~args: + Arg. + [ arg "accountInfos" ~doc:"Token id of the account to check" + ~typ: + (non_null (list (non_null Types.Input.AccountInfo.arg_typ))) + ; arg "stateHash" ~doc:"Hash of the snarked ledger to check" + ~typ:(non_null string) + ] + ~typ: + (non_null (list (non_null Types.SnarkedLedgerMembership.encoded_obj))) + ~resolve: + (resolve_membership + ~mapper:Types.SnarkedLedgerMembership.of_encoded_account ) end let genesis_constants = diff --git a/src/lib/mina_graphql/types.ml b/src/lib/mina_graphql/types.ml index a831a0b93eb..a1c017cc9f7 100644 --- a/src/lib/mina_graphql/types.ml +++ b/src/lib/mina_graphql/types.ml @@ -772,6 +772,30 @@ let snarked_ledger_state : ] ) module SnarkedLedgerMembership = struct + type encoded_account = { account : string; proof : Ledger.path } + + let encoded_obj = + obj "EncodedAccount" ~fields:(fun _ -> + [ field "account" + ~args:Arg.[] + ~doc:"Base64 encoded account as binable wire type" + ~typ:(non_null string) + ~resolve:(fun _ { account; _ } -> account) + ; field "merklePath" + ~args:Arg.[] + ~doc:"Membership proof in the snarked ledger" + ~typ:(non_null (list (non_null merkle_path_element))) + ~resolve:(fun _ { proof; _ } -> proof) + ] ) + + let of_encoded_account (proof : Ledger.path) (account : Account.t) : + encoded_account = + let account = + Binable.to_string (module Account.Binable_arg.Stable.Latest) account + |> Base64.encode_exn + in + { account; proof } + type t = { account_balance : Currency.Balance.t ; timing_info : Account_timing.t From 1854932d3eb26923b56d06b1225699a2a6a0028a Mon Sep 17 00:00:00 2001 From: sai Date: Mon, 2 Sep 2024 17:09:31 -0400 Subject: [PATCH 3/4] adding query to the command list --- src/lib/mina_graphql/mina_graphql.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/mina_graphql/mina_graphql.ml b/src/lib/mina_graphql/mina_graphql.ml index 83b9e043b87..e5131b794a0 100644 --- a/src/lib/mina_graphql/mina_graphql.ml +++ b/src/lib/mina_graphql/mina_graphql.ml @@ -2758,6 +2758,7 @@ module Queries = struct ; snark_pool ; pending_snark_work ; SnarkedLedgerMembership.snarked_ledger_account_membership + ; SnarkedLedgerMembership.encoded_snarked_ledger_account_membership ; genesis_constants ; time_offset ; validate_payment From 11db54fb8fad7a8741b501ee20d3e3313fdf4bf2 Mon Sep 17 00:00:00 2001 From: sai Date: Tue, 3 Sep 2024 03:27:35 -0400 Subject: [PATCH 4/4] gql schema changes --- graphql_schema.json | 113 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/graphql_schema.json b/graphql_schema.json index 95c11fb176d..78fe292b1c0 100644 --- a/graphql_schema.json +++ b/graphql_schema.json @@ -6470,6 +6470,57 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "EncodedAccount", + "description": null, + "fields": [ + { + "name": "account", + "description": "Base64 encoded account as binable wire type", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "merklePath", + "description": "Membership proof in the snarked ledger", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MerklePathElement", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "AccountInput", @@ -15293,6 +15344,68 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "encodedSnarkedLedgerAccountMembership", + "description": + "obtain a membership proof for an account in the snarked ledger along with the accounts full information encoded as base64 binable type", + "args": [ + { + "name": "stateHash", + "description": "Hash of the snarked ledger to check", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "accountInfos", + "description": "Token id of the account to check", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AccountInput", + "ofType": null + } + } + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "EncodedAccount", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "genesisConstants", "description":