Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sai/query snarked ledger compatible #15987

Merged
merged 12 commits into from
Aug 29, 2024
201 changes: 201 additions & 0 deletions graphql_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -6470,6 +6470,145 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "AccountInput",
"description": "An account with a public key and a token id",
"fields": [
{
"name": "token",
"description": "Token id of the account",
"args": [],
"type": { "kind": "SCALAR", "name": "TokenId", "ofType": null },
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "publicKey",
"description": "Public key of the account",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "PublicKey",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": [
{
"name": "token",
"description": "Token id of the account",
"type": { "kind": "SCALAR", "name": "TokenId", "ofType": null },
"defaultValue": null
},
{
"name": "publicKey",
"description": "Public key of the account",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "PublicKey",
"ofType": null
}
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "MembershipInfo",
"description": null,
"fields": [
{
"name": "accountBalance",
"description": "Account balance for a pk and token pair",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Balance",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "timingInfo",
"description": "Account timing according to chain state",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "AccountTiming",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nonce",
"description": "current nonce related to the account",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "UInt32",
"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": "OBJECT",
"name": "WorkDescription",
Expand Down Expand Up @@ -15092,6 +15231,68 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "snarkedLedgerAccountMembership",
"description":
"obtain a membership proof for an account in the snarked ledger along with the account's balance, timing information, and nonce",
"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": "MembershipInfo",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "genesisConstants",
"description":
Expand Down
57 changes: 57 additions & 0 deletions src/lib/mina_graphql/mina_graphql.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2192,6 +2192,62 @@ 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"
~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:(fun { 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 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 ) )
in
Ok memberships )

let genesis_constants =
field "genesisConstants"
~doc:
Expand Down Expand Up @@ -2677,6 +2733,7 @@ module Queries = struct
; trust_status_all
; snark_pool
; pending_snark_work
; snarked_ledger_account_membership
; genesis_constants
; time_offset
; validate_payment
Expand Down
47 changes: 47 additions & 0 deletions src/lib/mina_graphql/types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,38 @@ let snarked_ledger_state :
~resolve:(fun _ ({ sok_digest = _; _ } : _ M.t) -> None)
] )

module SnarkedLedgerMembership = struct
type t =
{ account_balance : Currency.Balance.t
; timing_info : Account_timing.t
; nonce : Account.Nonce.t
; proof : Ledger.path
}

let obj =
obj "MembershipInfo" ~fields:(fun _ ->
[ field "accountBalance"
~args:Arg.[]
~doc:"Account balance for a pk and token pair"
~typ:(non_null balance)
~resolve:(fun _ { account_balance; _ } -> account_balance)
; field "timingInfo"
~args:Arg.[]
~doc:"Account timing according to chain state"
~typ:(non_null account_timing)
~resolve:(fun _ { timing_info; _ } -> timing_info)
; field "nonce"
~args:Arg.[]
~doc:"current nonce related to the account" ~typ:(non_null uint32)
~resolve:(fun _ { nonce; _ } -> Account.Nonce.to_uint32 nonce)
; field "merklePath"
~args:Arg.[]
~doc:"Membership proof in the snarked ledger"
~typ:(non_null (list (non_null merkle_path_element)))
~resolve:(fun _ { proof; _ } -> proof)
] )
end

let blockchain_state :
( Mina_lib.t
, (Mina_state.Blockchain_state.Value.t * State_hash.t) option )
Expand Down Expand Up @@ -2419,6 +2451,21 @@ module Input = struct
| (h : input) -> `String (Frozen_ledger_hash.to_base58_check h) )
end

module AccountInfo = struct
let arg_typ :
( (PublicKey.input * TokenId.input option) option
, (PublicKey.input * TokenId.input option) option )
arg_typ =
obj "AccountInput" ~doc:"An account with a public key and a token id"
~coerce:(fun public_key token -> (public_key, token))
~fields:
[ arg "publicKey" ~doc:"Public key of the account"
~typ:(non_null PublicKey.arg_typ)
; arg "token" ~doc:"Token id of the account" ~typ:TokenId.arg_typ
]
~split:(fun f (pk, token) -> f pk token)
end

module BlockTime = struct
type input = Block_time.t

Expand Down