diff --git a/graphql_schema.json b/graphql_schema.json index 78fe292b1c0..a24becb0e8e 100644 --- a/graphql_schema.json +++ b/graphql_schema.json @@ -95,6 +95,16 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "SCALAR", + "name": "ProofBundle", + "description": "Proof bundle for a given spec in json format", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "SCALAR", "name": "RosettaTransaction", @@ -5490,6 +5500,38 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "sendProofBundle", + "description": "Transaction SNARKs for a given spec", + "args": [ + { + "name": "input", + "description": + "Proof bundle for a given spec in json format including fees and prover public key", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ProofBundle", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, diff --git a/src/lib/mina_graphql/mina_graphql.ml b/src/lib/mina_graphql/mina_graphql.ml index 0378ca6bece..b55afb91bed 100644 --- a/src/lib/mina_graphql/mina_graphql.ml +++ b/src/lib/mina_graphql/mina_graphql.ml @@ -785,6 +785,41 @@ module Mutations = struct Error "Internal error: response from transaction pool was malformed" ) + let add_snark_work = + io_field "sendProofBundle" ~doc:"Transaction SNARKs for a given spec" + ~args: + Arg. + [ arg "input" + ~doc: + "Proof bundle for a given spec in json format including fees \ + and prover public key" + ~typ:(non_null Types.Input.ProofBundleInput.arg_typ) + ] + ~typ:(non_null string) + ~resolve:(fun { ctx = mina; _ } () + (proof_bundle : + Ledger_proof.t + Snark_work_lib.Work.Result_without_metrics.t ) -> + let solved_work = + Network_pool.Snark_pool.Resource_pool.Diff.Add_solved_work + ( proof_bundle.statements + , { proof = proof_bundle.proofs + ; fee = { fee = proof_bundle.fee; prover = proof_bundle.prover } + } ) + in + match%map Mina_lib.add_work_graphql mina solved_work with + | Ok + ( `Broadcasted + , Network_pool.Snark_pool.Resource_pool.Diff.Add_solved_work _ + , _ ) -> + Ok "Accepted" + | Error err -> + Error (Error.to_string_hum err) + | Ok _ -> + Error + "Internal error: Transaction proofs could not be added to the \ + pool" ) + let export_logs = io_field "exportLogs" ~doc:"Export daemon logs to tar archive" ~args:Arg.[ arg "basename" ~typ:string ] @@ -1006,6 +1041,7 @@ module Mutations = struct ; archive_precomputed_block ; archive_extensional_block ; send_rosetta_transaction + ; add_snark_work ] module Itn = struct diff --git a/src/lib/mina_graphql/types.ml b/src/lib/mina_graphql/types.ml index a1c017cc9f7..e3aa5bb2bee 100644 --- a/src/lib/mina_graphql/types.ml +++ b/src/lib/mina_graphql/types.ml @@ -2581,6 +2581,21 @@ module Input = struct Yojson.Safe.to_basic @@ Mina_base.Zkapp_command.to_json x ) end + module ProofBundleInput = struct + type input = Ledger_proof.t Snark_work_lib.Work.Result_without_metrics.t + + let arg_typ = + scalar "ProofBundle" ~doc:"Proof bundle for a given spec in json format" + ~coerce:(fun json -> + let json = Utils.to_yojson json in + Snark_work_lib.Work.Result_without_metrics.of_yojson + Ledger_proof.of_yojson json ) + ~to_json:(fun (res : input) -> + Snark_work_lib.Work.Result_without_metrics.to_yojson + Ledger_proof.to_yojson res + |> Yojson.Safe.to_basic ) + end + module PrecomputedBlock = struct type input = Mina_block.Precomputed.t diff --git a/src/lib/mina_lib/mina_lib.ml b/src/lib/mina_lib/mina_lib.ml index 7434444ff52..34c83b00ae4 100644 --- a/src/lib/mina_lib/mina_lib.ml +++ b/src/lib/mina_lib/mina_lib.ml @@ -901,6 +901,13 @@ let add_work t (work : Snark_worker_lib.Work.Result.t) = (Network_pool.Snark_pool.Resource_pool.Diff.of_result work, cb) |> Deferred.don't_wait_for +let add_work_graphql t diff = + let results_ivar = Ivar.create () in + Network_pool.Snark_pool.Local_sink.push t.pipes.snark_local_sink + (diff, Ivar.fill results_ivar) + |> Deferred.don't_wait_for ; + Ivar.read results_ivar + let get_current_nonce t aid = match Participating_state.active diff --git a/src/lib/mina_lib/mina_lib.mli b/src/lib/mina_lib/mina_lib.mli index 0789d030d3d..3fddaa8bcf3 100644 --- a/src/lib/mina_lib/mina_lib.mli +++ b/src/lib/mina_lib/mina_lib.mli @@ -111,6 +111,14 @@ val work_selection_method : t -> (module Work_selector.Selection_method_intf) val add_work : t -> Snark_worker.Work.Result.t -> unit +val add_work_graphql : + t + -> Network_pool.Snark_pool.Resource_pool.Diff.t + -> ( [ `Broadcasted | `Not_broadcasted ] + * Network_pool.Snark_pool.Resource_pool.Diff.t + * Network_pool.Snark_pool.Resource_pool.Diff.rejected ) + Deferred.Or_error.t + val snark_job_state : t -> Work_selector.State.t val get_current_nonce : diff --git a/src/lib/snark_work_lib/work.ml b/src/lib/snark_work_lib/work.ml index c89f64ade51..cd5b3de7045 100644 --- a/src/lib/snark_work_lib/work.ml +++ b/src/lib/snark_work_lib/work.ml @@ -99,3 +99,13 @@ module Result = struct end end] end + +module Result_without_metrics = struct + type 'proof t = + { proofs : 'proof One_or_two.t + ; statements : Transaction_snark.Statement.t One_or_two.t + ; prover : Signature_lib.Public_key.Compressed.t + ; fee : Currency.Fee.t + } + [@@deriving yojson] +end