Skip to content

GraphQL: add a query to fetch specific pending snark work #16244

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

Merged
merged 11 commits into from
Dec 9, 2024
Merged
52 changes: 52 additions & 0 deletions graphql_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -15282,6 +15282,58 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "pendingSnarkWorkRange",
"description":
"Find any sequence of pending snark works between two indexes in the pending snark work pool",
"args": [
{
"name": "endingIndex",
"description":
"The last index to be taken from the pending snark work pool (excluded). If not specified or greater than the pending snark work list, all elements from index [startingIndex] will be returned. An empty list will be returned if startingIndex is not a valid index of the pending snark work list or if startingIndex >= endingIndex.",
"type": {
"kind": "SCALAR",
"name": "UInt32",
"ofType": null
},
"defaultValue": null
},
{
"name": "startingIndex",
"description":
"The first index to be taken from the pending snark work pool",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "UInt32",
"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": "PendingSnarkWork",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "snarkedLedgerAccountMembership",
"description":
Expand Down
65 changes: 57 additions & 8 deletions src/lib/mina_graphql/mina_graphql.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2202,19 +2202,67 @@ module Queries = struct
Mina_lib.snark_pool mina |> Network_pool.Snark_pool.resource_pool
|> Network_pool.Snark_pool.Resource_pool.all_completed_work )

(* Auxiliary function to fetch all pending work *)
let get_pending_work mina =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this is slightly misnamed now. The design has changed from the previous intention. Previously we obtained all pending work without fees, where as now it seems we obtain all work, including work that was previously completed in case another snark worker want to provide a better bid. I feel this change in intention should be documented and explained in this doc comment.

perhaps something like:
get_pending_and_completed_work

let snark_job_state = Mina_lib.snark_job_state mina in
let snark_pool = Mina_lib.snark_pool mina in
let fee_opt =
Mina_lib.(
Option.map (snark_worker_key mina) ~f:(fun _ -> snark_work_fee mina))
in
Work_selector.pending_work_statements ~snark_pool ~fee_opt snark_job_state

let pending_snark_work =
field "pendingSnarkWork" ~doc:"List of snark works that are yet to be done"
~args:Arg.[]
~typ:(non_null @@ list @@ non_null Types.pending_work)
~resolve:(fun { ctx = mina; _ } () ->
let snark_job_state = Mina_lib.snark_job_state mina in
let snark_pool = Mina_lib.snark_pool mina in
let fee_opt =
Mina_lib.(
Option.map (snark_worker_key mina) ~f:(fun _ -> snark_work_fee mina))
~resolve:(fun { ctx = mina; _ } () -> get_pending_work mina)

let pending_snark_work_range =
field "pendingSnarkWorkRange"
~doc:
"Find any sequence of pending snark works between two indexes in the \
pending snark work pool"
~args:
Arg.
[ arg "startingIndex"
~doc:
"The first index to be taken from the pending snark work pool"
~typ:(non_null Types.Input.UInt32.arg_typ)
; arg "endingIndex"
~doc:
"The last index to be taken from the pending snark work pool \
(excluded). If not specified or greater than the pending \
snark work list, all elements from index [startingIndex] will \
be returned. An empty list will be returned if startingIndex \
is not a valid index of the pending snark work list or if \
startingIndex >= endingIndex."
~typ:Types.Input.UInt32.arg_typ
]
~typ:(non_null @@ list @@ non_null Types.pending_work)
~resolve:(fun { ctx = mina; _ } () start_idx end_idx ->
let pending_work = get_pending_work mina in
let pending_work_size =
pending_work |> List.length |> Unsigned.UInt32.of_int
in
Work_selector.pending_work_statements ~snark_pool ~fee_opt
snark_job_state )
let less_than uint1 uint2 = Unsigned.UInt32.compare uint1 uint2 < 0 in
match end_idx with
| None when less_than start_idx pending_work_size ->
(* drop handles case when start_idx is greater than pending work and is O(start_idx)*)
let start = Unsigned.UInt32.to_int start_idx in
List.drop pending_work start
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit
drop returns empty list when the start index is greater than the list size, so you don't really need the check, but it is fine to leave it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s good to know !

I’m in favor to leave it to make the behavior explicit, but I don’t have a strong opinion about it.

Copy link
Member

@svv232 svv232 Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya that is fine, i mentioned it in the comment to clarify as well on line 2247

| Some end_idx
when less_than start_idx end_idx
&& less_than start_idx pending_work_size ->
let pos = Unsigned.UInt32.to_int start_idx in
let len =
Unsigned.UInt32.(
min (sub end_idx start_idx) (sub pending_work_size start_idx)
|> to_int)
in
List.sub ~pos ~len pending_work
| _ ->
[] )

module SnarkedLedgerMembership = struct
let resolve_membership :
Expand Down Expand Up @@ -2784,6 +2832,7 @@ module Queries = struct
; trust_status_all
; snark_pool
; pending_snark_work
; pending_snark_work_range
; SnarkedLedgerMembership.snarked_ledger_account_membership
; SnarkedLedgerMembership.encoded_snarked_ledger_account_membership
; genesis_constants
Expand Down