-
Notifications
You must be signed in to change notification settings - Fork 566
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
Conversation
src/lib/mina_graphql/mina_graphql.ml
Outdated
(included). If not specified, only the work at index \ | ||
[startingIndex] will be returned. An empty list will be \ | ||
returned if startingIndex > endingIndex" | ||
~typ:Types.Input.UInt32.arg_typ ~default:Unsigned.UInt32.max_int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My personal preference, would for this to also be non-null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect this working if startingIndex = endingIndex = 0
, so I would not be in favor to expect endingIndex ≠ 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the upper bound was exclusive instead? i.e 0-1 gets the first index. Also If I am calling an API end point that returns a range, I would expect n-null to return the list from the index n to the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, it is counter intuitive for me when for the range n to max-int it returns only the element at index n
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the default behavior. Now
- if
endingIndex ≥ length(pending_work)
, everything fromstartingIndex
is returned. (max_int
is still the default) endingIndex
is excluded[]
is returned whenstartingIndex ≥ endingIndex
orstartingIndex ≥ length(pending_work)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still thinking having max-int is unnecessary logic. I think we can come up with a solution that removes this and enforces the invariants we know to be true. For example
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, endingIndex] is not a valid range of the \
pending snark work list."
~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
let less_than uint1 uint2 = Unsigned.UInt32.compare uint1 uint2 < 0 in
match end_idx with
| None ->
(* 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
| Some end_idx when less_than start_idx end_idx && less_than end_idx pending_work_size ->
let pos = Unsigned.UInt32.to_int start_idx in
let len = Unsigned.UInt32.(sub end_idx start_idx |> to_int) in
List.sub ~pos ~len pending_work
| _ ->
[] )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for prefering UInt32 manipulation over to_int conversion from the start ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to run any transformations on user controlled data before checking, and it was more convenient to write with the match case. You can do uint to int conversions safely, but I wasn't sure how the js one was implemented. I just took the safe route without reading the implementation. Maybe it's also worth having some error checking in the None case as well for start idx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed a new version with your suggestion but I modified some match cases to match the spec.
src/lib/mina_graphql/mina_graphql.ml
Outdated
in | ||
Work_selector.pending_work_statements ~snark_pool ~fee_opt | ||
snark_job_state ) | ||
try List.sub ~pos:start_idx ~len @@ get_pending_work mina with _ -> [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am fine with a slice here because the Janestreet runtime is O(n), and we won't actually save on significant ram usage because work selection stores state.available jobs anyway in work_lib. Since state.availabe jobs is a super set of the pending work, we wouldn't save much space overall i.e worst case O(2n)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is also currently a low frequency graphql call
src/app/cli/src/init/client.ml
Outdated
let pending_snark_work_range = | ||
Command.async | ||
~summary: | ||
"Range of snark works in JSON format that are not available in the pool \ | ||
yet" | ||
pending_snark_work_list |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this also splice with a start and end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, & this is actually unrelated, I’ll remove it from these commits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that makes sense, I thought the client and graphql changes could be split up but i didn't really mind.
65f30d1
to
bed927c
Compare
module Pending_snark_work_range = | ||
[%graphql | ||
{| | ||
query pendingSnarkWorkRange { | ||
pendingSnarkWork { | ||
workBundle { | ||
source_first_pass_ledger_hash: sourceFirstPassLedgerHash | ||
target_first_pass_ledger_hash: targetFirstPassLedgerHash | ||
source_second_pass_ledger_hash: sourceSecondPassLedgerHash | ||
target_second_pass_ledger_hash: targetSecondPassLedgerHash | ||
fee_excess: feeExcess { | ||
feeTokenLeft | ||
feeExcessLeft { | ||
sign | ||
feeMagnitude | ||
} | ||
feeTokenRight | ||
feeExcessRight { | ||
sign | ||
feeMagnitude | ||
} | ||
} | ||
supply_increase : supplyIncrease | ||
work_id: workId | ||
} | ||
} | ||
} | ||
|}] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think should also be deleted for now, until/if the client command is added back
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, deleted
bed927c
to
2d977f5
Compare
2d977f5
to
d5882ba
Compare
src/lib/mina_graphql/mina_graphql.ml
Outdated
| 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
!ci-build-me |
!ci-nightly-me |
!ci-build-me |
src/lib/mina_graphql/mina_graphql.ml
Outdated
@@ -2202,19 +2202,69 @@ 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 = |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic looks good, I just wanted you to change the pending_snark_work
graphql name to something more apt. It seems the goal now is to get all work indexes in the case an external snark work script want to re-do work at a better price.
This function was initially added to unify code. At this point this is no longer relevant, as it is now used only in one place.
!ci-build-me |
!ci-build-me |
This PR adds the possibility to fetch a specific range of work in the pending snark work list with GraphQL.