Baker: add client-side validation
This commit is contained in:
parent
0512ff55ce
commit
ea9b3ae68c
@ -9,6 +9,7 @@
|
|||||||
tezos-shell-services
|
tezos-shell-services
|
||||||
tezos-client-base
|
tezos-client-base
|
||||||
tezos-rpc
|
tezos-rpc
|
||||||
|
tezos-storage
|
||||||
tezos-signer-backends
|
tezos-signer-backends
|
||||||
bip39))
|
bip39))
|
||||||
(library_flags (:standard -linkall))
|
(library_flags (:standard -linkall))
|
||||||
@ -17,6 +18,7 @@
|
|||||||
-open Tezos_base__TzPervasives
|
-open Tezos_base__TzPervasives
|
||||||
-open Tezos_shell_services
|
-open Tezos_shell_services
|
||||||
-open Tezos_client_base
|
-open Tezos_client_base
|
||||||
|
-open Tezos_storage
|
||||||
-open Tezos_rpc))))
|
-open Tezos_rpc))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
module Name = struct let name = "alpha" end
|
module Name = struct let name = "alpha" end
|
||||||
module Alpha_environment = Tezos_protocol_environment_faked.MakeV1(Name)()
|
module T = Tezos_protocol_environment.Make(Tezos_storage.Context)
|
||||||
|
module Alpha_environment = T.MakeV1(Name)()
|
||||||
|
|
||||||
module Proto = Tezos_protocol_alpha.Functor.Make(Alpha_environment)
|
module Proto = Tezos_protocol_alpha.Functor.Make(Alpha_environment)
|
||||||
module Alpha_block_services = Block_services.Make(Proto)(Proto)
|
module Alpha_block_services = Block_services.Make(Proto)(Proto)
|
||||||
|
|
||||||
include Proto
|
include Proto
|
||||||
|
|
||||||
class type rpc_context = object
|
class type rpc_context = object
|
||||||
|
@ -19,6 +19,7 @@ type block_info = {
|
|||||||
protocol: Protocol_hash.t ;
|
protocol: Protocol_hash.t ;
|
||||||
next_protocol: Protocol_hash.t ;
|
next_protocol: Protocol_hash.t ;
|
||||||
level: Raw_level.t ;
|
level: Raw_level.t ;
|
||||||
|
context : Context_hash.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let raw_info cctxt ?(chain = `Main) hash shell_header =
|
let raw_info cctxt ?(chain = `Main) hash shell_header =
|
||||||
@ -27,12 +28,13 @@ let raw_info cctxt ?(chain = `Main) hash shell_header =
|
|||||||
Shell_services.Blocks.protocols
|
Shell_services.Blocks.protocols
|
||||||
cctxt ~chain ~block () >>=? fun { current_protocol = protocol ;
|
cctxt ~chain ~block () >>=? fun { current_protocol = protocol ;
|
||||||
next_protocol } ->
|
next_protocol } ->
|
||||||
let { Tezos_base.Block_header.predecessor ; fitness ; timestamp ; level ; _ } =
|
let { Tezos_base.Block_header.predecessor ; fitness ;
|
||||||
|
timestamp ; level ; context ; _ } =
|
||||||
shell_header in
|
shell_header in
|
||||||
match Raw_level.of_int32 level with
|
match Raw_level.of_int32 level with
|
||||||
| Ok level ->
|
| Ok level ->
|
||||||
return { hash ; chain_id ; predecessor ; fitness ;
|
return { hash ; chain_id ; predecessor ; fitness ;
|
||||||
timestamp ; protocol ; next_protocol ; level }
|
timestamp ; protocol ; next_protocol ; level ; context }
|
||||||
| Error _ ->
|
| Error _ ->
|
||||||
failwith "Cannot convert level into int32"
|
failwith "Cannot convert level into int32"
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ type block_info = {
|
|||||||
protocol: Protocol_hash.t ;
|
protocol: Protocol_hash.t ;
|
||||||
next_protocol: Protocol_hash.t ;
|
next_protocol: Protocol_hash.t ;
|
||||||
level: Raw_level.t ;
|
level: Raw_level.t ;
|
||||||
|
context : Context_hash.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
val info:
|
val info:
|
||||||
|
@ -18,9 +18,21 @@ let generate_proof_of_work_nonce () =
|
|||||||
let generate_seed_nonce () =
|
let generate_seed_nonce () =
|
||||||
match Nonce.of_bytes @@
|
match Nonce.of_bytes @@
|
||||||
Rand.generate Constants.nonce_length with
|
Rand.generate Constants.nonce_length with
|
||||||
| Error _ -> assert false
|
| Error _errs -> assert false
|
||||||
| Ok nonce -> nonce
|
| Ok nonce -> nonce
|
||||||
|
|
||||||
|
let rec retry_call f ?(msg="Call error") ?(n=5) () =
|
||||||
|
f () >>= function
|
||||||
|
| Ok r -> return r
|
||||||
|
| (Error errs) as x ->
|
||||||
|
if n > 0 then
|
||||||
|
begin
|
||||||
|
lwt_log_error "%s\n%a\nRetrying..."
|
||||||
|
msg pp_print_error errs >>= fun () ->
|
||||||
|
Lwt_unix.sleep 1. >>= retry_call f ~msg ~n:(n-1)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Lwt.return x
|
||||||
|
|
||||||
let forge_block_header
|
let forge_block_header
|
||||||
(cctxt : #Proto_alpha.full)
|
(cctxt : #Proto_alpha.full)
|
||||||
@ -370,14 +382,16 @@ let rec insert_baking_slot slot = function
|
|||||||
|
|
||||||
type state = {
|
type state = {
|
||||||
genesis: Block_hash.t ;
|
genesis: Block_hash.t ;
|
||||||
|
index : Context.index ;
|
||||||
mutable delegates: public_key_hash list ;
|
mutable delegates: public_key_hash list ;
|
||||||
mutable best: Client_baking_blocks.block_info ;
|
mutable best: Client_baking_blocks.block_info ;
|
||||||
mutable future_slots:
|
mutable future_slots:
|
||||||
(Time.t * (Client_baking_blocks.block_info * int * public_key_hash)) list ;
|
(Time.t * (Client_baking_blocks.block_info * int * public_key_hash)) list ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let create_state genesis delegates best =
|
let create_state genesis index delegates best =
|
||||||
{ genesis ;
|
{ genesis ;
|
||||||
|
index ;
|
||||||
delegates ;
|
delegates ;
|
||||||
best ;
|
best ;
|
||||||
future_slots = [] ;
|
future_slots = [] ;
|
||||||
@ -491,6 +505,42 @@ let pop_baking_slots state =
|
|||||||
state.future_slots <- future_slots ;
|
state.future_slots <- future_slots ;
|
||||||
slots
|
slots
|
||||||
|
|
||||||
|
|
||||||
|
let filter_invalid_operations (cctxt : #full) state block_info (operations : packed_operation list list) =
|
||||||
|
let open Client_baking_simulator in
|
||||||
|
lwt_debug "Starting client-side validation" >>= fun () ->
|
||||||
|
begin_construction cctxt state.index block_info >>=? fun initial_inc ->
|
||||||
|
let endorsements = List.nth operations 0 in
|
||||||
|
let votes = List.nth operations 1 in
|
||||||
|
let anonymous = List.nth operations 2 in
|
||||||
|
let managers = List.nth operations 3 in
|
||||||
|
(* TODO log *)
|
||||||
|
let validate_operation inc op =
|
||||||
|
add_operation inc op >>= function
|
||||||
|
| Error _ -> return None
|
||||||
|
| Ok inc -> return (Some inc)
|
||||||
|
in
|
||||||
|
let filter_valid_operations inc ops =
|
||||||
|
fold_left_s (fun (inc, acc) op ->
|
||||||
|
validate_operation inc op >>=? function
|
||||||
|
| None -> return (inc, acc)
|
||||||
|
| Some inc -> return (inc, op :: acc)
|
||||||
|
) (inc, []) ops
|
||||||
|
in
|
||||||
|
let is_valid_endorsement endorsement =
|
||||||
|
validate_operation initial_inc endorsement >>=? function
|
||||||
|
| None -> return None
|
||||||
|
| Some inc -> finalize_construction inc >>= begin function
|
||||||
|
| Ok _ -> return (Some endorsement)
|
||||||
|
| Error _ -> return None
|
||||||
|
end
|
||||||
|
in
|
||||||
|
filter_map_s is_valid_endorsement endorsements >>=? fun _endorsements ->
|
||||||
|
filter_valid_operations initial_inc votes >>=? fun (inc, votes) ->
|
||||||
|
filter_valid_operations inc anonymous >>=? fun (inc, anonymous) ->
|
||||||
|
filter_valid_operations inc managers >>=? fun (_, managers) ->
|
||||||
|
return @@ List.map List.rev [ endorsements ; votes ; anonymous ; managers ]
|
||||||
|
|
||||||
let bake_slot
|
let bake_slot
|
||||||
cctxt
|
cctxt
|
||||||
state
|
state
|
||||||
@ -525,9 +575,27 @@ let bake_slot
|
|||||||
let protocol_data =
|
let protocol_data =
|
||||||
forge_faked_protocol_data ~priority ~seed_nonce_hash in
|
forge_faked_protocol_data ~priority ~seed_nonce_hash in
|
||||||
let operations = classify_operations operations in
|
let operations = classify_operations operations in
|
||||||
|
(* Don't validate if current block is genesis *)
|
||||||
|
begin
|
||||||
|
(* Don't load an alpha context if still in genesis *)
|
||||||
|
if Protocol_hash.(bi.protocol = bi.next_protocol) then
|
||||||
|
filter_invalid_operations cctxt state bi operations
|
||||||
|
else
|
||||||
|
return operations
|
||||||
|
end >>= function
|
||||||
|
| Error errs ->
|
||||||
|
lwt_log_error "Error while filtering invalid operations (client-side) :@\n%a"
|
||||||
|
pp_print_error
|
||||||
|
errs >>= fun () ->
|
||||||
|
return None
|
||||||
|
| Ok operations ->
|
||||||
|
retry_call
|
||||||
|
(fun () ->
|
||||||
Alpha_block_services.Helpers.Preapply.block
|
Alpha_block_services.Helpers.Preapply.block
|
||||||
cctxt ~chain ~block
|
cctxt ~chain ~block
|
||||||
~timestamp ~sort:true ~protocol_data operations >>= function
|
~timestamp ~sort:true ~protocol_data operations)
|
||||||
|
~msg:"Error while prevalidating operations" ()
|
||||||
|
>>= function
|
||||||
| Error errs ->
|
| Error errs ->
|
||||||
lwt_log_error "Error while prevalidating operations:@\n%a"
|
lwt_log_error "Error while prevalidating operations:@\n%a"
|
||||||
pp_print_error
|
pp_print_error
|
||||||
@ -635,6 +703,7 @@ let check_error p =
|
|||||||
let create
|
let create
|
||||||
(cctxt : #Proto_alpha.full)
|
(cctxt : #Proto_alpha.full)
|
||||||
?max_priority
|
?max_priority
|
||||||
|
~(context_path: string)
|
||||||
(delegates: public_key_hash list)
|
(delegates: public_key_hash list)
|
||||||
(block_stream: Client_baking_blocks.block_info tzresult Lwt_stream.t)
|
(block_stream: Client_baking_blocks.block_info tzresult Lwt_stream.t)
|
||||||
(bi: Client_baking_blocks.block_info) =
|
(bi: Client_baking_blocks.block_info) =
|
||||||
@ -651,7 +720,9 @@ let create
|
|||||||
last_get_block := Some t ;
|
last_get_block := Some t ;
|
||||||
t
|
t
|
||||||
| Some t -> t in
|
| Some t -> t in
|
||||||
let state = create_state genesis_hash delegates bi in
|
lwt_debug "Opening shell context" >>= fun () ->
|
||||||
|
Client_baking_simulator.load_context ~context_path >>= fun index ->
|
||||||
|
let state = create_state genesis_hash index delegates bi in
|
||||||
check_error @@ insert_block cctxt ?max_priority state bi >>= fun () ->
|
check_error @@ insert_block cctxt ?max_priority state bi >>= fun () ->
|
||||||
|
|
||||||
(* main loop *)
|
(* main loop *)
|
||||||
@ -694,16 +765,15 @@ let create
|
|||||||
cctxt#message "Starting the baker" >>= fun () ->
|
cctxt#message "Starting the baker" >>= fun () ->
|
||||||
worker_loop ()
|
worker_loop ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(* Wrapper around previous [create] function that handles the case of
|
(* Wrapper around previous [create] function that handles the case of
|
||||||
unavailable blocks (empty block chain). *)
|
unavailable blocks (empty block chain). *)
|
||||||
let create
|
let create
|
||||||
(cctxt : #Proto_alpha.full)
|
(cctxt : #Proto_alpha.full)
|
||||||
?max_priority
|
?max_priority
|
||||||
|
~(context_path: string)
|
||||||
(delegates: public_key_hash list)
|
(delegates: public_key_hash list)
|
||||||
(block_stream: Client_baking_blocks.block_info tzresult Lwt_stream.t) =
|
(block_stream: Client_baking_blocks.block_info tzresult Lwt_stream.t) =
|
||||||
Client_baking_scheduling.wait_for_first_block
|
Client_baking_scheduling.wait_for_first_block
|
||||||
~info:cctxt#message
|
~info:cctxt#message
|
||||||
block_stream
|
block_stream
|
||||||
(create cctxt ?max_priority delegates block_stream)
|
(create cctxt ?max_priority ~context_path delegates block_stream)
|
||||||
|
@ -79,6 +79,7 @@ end
|
|||||||
val create:
|
val create:
|
||||||
#Proto_alpha.full ->
|
#Proto_alpha.full ->
|
||||||
?max_priority: int ->
|
?max_priority: int ->
|
||||||
|
context_path: string ->
|
||||||
public_key_hash list ->
|
public_key_hash list ->
|
||||||
Client_baking_blocks.block_info tzresult Lwt_stream.t ->
|
Client_baking_blocks.block_info tzresult Lwt_stream.t ->
|
||||||
unit tzresult Lwt.t
|
unit tzresult Lwt.t
|
||||||
|
@ -101,31 +101,3 @@ let reveal_nonces cctxt () =
|
|||||||
Client_baking_forge.get_unrevealed_nonces
|
Client_baking_forge.get_unrevealed_nonces
|
||||||
cctxt cctxt#block >>=? fun nonces ->
|
cctxt cctxt#block >>=? fun nonces ->
|
||||||
do_reveal cctxt cctxt#block nonces
|
do_reveal cctxt cctxt#block nonces
|
||||||
|
|
||||||
let run_daemon cctxt ?max_priority ~endorsement_delay delegates ~endorsement ~baking ~denunciation =
|
|
||||||
let endorser =
|
|
||||||
if endorsement then
|
|
||||||
Client_daemon.Endorser.run cctxt
|
|
||||||
~delay:endorsement_delay
|
|
||||||
~min_date:((Time.add (Time.now ()) (Int64.neg 1800L)))
|
|
||||||
delegates >>=? fun () -> return ()
|
|
||||||
else return ()
|
|
||||||
in
|
|
||||||
let baker =
|
|
||||||
if baking then
|
|
||||||
Client_daemon.Baker.run cctxt
|
|
||||||
?max_priority
|
|
||||||
~min_date:((Time.add (Time.now ()) (Int64.neg 1800L)))
|
|
||||||
delegates >>=? fun () -> return ()
|
|
||||||
else return ()
|
|
||||||
in
|
|
||||||
let accuser =
|
|
||||||
if denunciation then
|
|
||||||
Client_daemon.Accuser.run cctxt >>=? fun () -> return ()
|
|
||||||
else
|
|
||||||
return ()
|
|
||||||
in
|
|
||||||
endorser >>=? fun () ->
|
|
||||||
baker >>=? fun () ->
|
|
||||||
accuser >>=? fun () ->
|
|
||||||
return ()
|
|
||||||
|
@ -45,14 +45,3 @@ val reveal_nonces :
|
|||||||
#Proto_alpha.full ->
|
#Proto_alpha.full ->
|
||||||
unit ->
|
unit ->
|
||||||
unit Error_monad.tzresult Lwt.t
|
unit Error_monad.tzresult Lwt.t
|
||||||
|
|
||||||
(** Initialize the baking daemon *)
|
|
||||||
val run_daemon:
|
|
||||||
#Proto_alpha.full ->
|
|
||||||
?max_priority:int ->
|
|
||||||
endorsement_delay:int ->
|
|
||||||
public_key_hash list ->
|
|
||||||
endorsement:bool ->
|
|
||||||
baking:bool ->
|
|
||||||
denunciation:bool ->
|
|
||||||
unit Error_monad.tzresult Lwt.t
|
|
||||||
|
64
src/proto_alpha/lib_delegate/client_baking_simulator.ml
Normal file
64
src/proto_alpha/lib_delegate/client_baking_simulator.ml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2018. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
open Proto_alpha
|
||||||
|
open Alpha_context
|
||||||
|
|
||||||
|
module Main = Alpha_environment.Lift(Main)
|
||||||
|
|
||||||
|
type incremental = {
|
||||||
|
predecessor: Client_baking_blocks.block_info ;
|
||||||
|
context : Context.t ;
|
||||||
|
state: Main.validation_state ;
|
||||||
|
rev_operations: Operation.packed list ;
|
||||||
|
header: Tezos_base.Block_header.shell_header ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let load_context ~context_path =
|
||||||
|
Context.init ~readonly:true context_path
|
||||||
|
|
||||||
|
let begin_construction (_cctxt : #Proto_alpha.full) index predecessor =
|
||||||
|
let { Client_baking_blocks.context } = predecessor in
|
||||||
|
Context.checkout_exn index context >>= fun context ->
|
||||||
|
let timestamp = Time.now () in
|
||||||
|
let predecessor_hash = predecessor.hash in
|
||||||
|
(* Shell_services.Blocks.header cctxt ~chain:`Main ~block:(`Hash (predecessor_hash, 0)) ()
|
||||||
|
* >>=? fun { shell ; _ } -> *)
|
||||||
|
let header : Tezos_base.Block_header.shell_header = Tezos_base.Block_header.{
|
||||||
|
predecessor = predecessor_hash ;
|
||||||
|
proto_level = 0 (* shell.proto_level *) ;
|
||||||
|
validation_passes = 0 (* shell.validation_passes *) ;
|
||||||
|
fitness = predecessor.fitness (* shell.fitness *) ;
|
||||||
|
timestamp ;
|
||||||
|
level = 0l (* shell.level *) ;
|
||||||
|
context = Context_hash.zero ;
|
||||||
|
operations_hash = Operation_list_list_hash.zero ;
|
||||||
|
} in
|
||||||
|
Main.begin_construction
|
||||||
|
~predecessor_context: context
|
||||||
|
~predecessor_timestamp: header.timestamp
|
||||||
|
~predecessor_fitness: header.fitness
|
||||||
|
~predecessor_level: header.level
|
||||||
|
~predecessor:predecessor_hash
|
||||||
|
~timestamp
|
||||||
|
() >>=? fun state ->
|
||||||
|
return {
|
||||||
|
predecessor ;
|
||||||
|
context ;
|
||||||
|
state ;
|
||||||
|
rev_operations = [] ;
|
||||||
|
header ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let add_operation st ( op : Operation.packed ) =
|
||||||
|
Main.apply_operation st.state op >>=? fun (state, _) ->
|
||||||
|
return { st with state ; rev_operations = op :: st.rev_operations }
|
||||||
|
|
||||||
|
let finalize_construction inc =
|
||||||
|
Main.finalize_block inc.state >>=? fun _ -> return ()
|
27
src/proto_alpha/lib_delegate/client_baking_simulator.mli
Normal file
27
src/proto_alpha/lib_delegate/client_baking_simulator.mli
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2018. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
open Proto_alpha
|
||||||
|
open Alpha_context
|
||||||
|
|
||||||
|
type incremental = {
|
||||||
|
predecessor: Client_baking_blocks.block_info ;
|
||||||
|
context : Context.t ;
|
||||||
|
state: Main.validation_state ;
|
||||||
|
rev_operations: Operation.packed list ;
|
||||||
|
header: Tezos_base.Block_header.shell_header ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val load_context : context_path:string -> Context.index Lwt.t
|
||||||
|
|
||||||
|
val begin_construction : #Proto_alpha.full -> Context.index -> Client_baking_blocks.block_info -> incremental tzresult Lwt.t
|
||||||
|
|
||||||
|
val add_operation : incremental -> Operation.packed -> incremental tzresult Lwt.t
|
||||||
|
|
||||||
|
val finalize_construction : incremental -> unit tzresult Lwt.t
|
@ -18,14 +18,13 @@ module Endorser = struct
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
module Baker = struct
|
module Baker = struct
|
||||||
|
|
||||||
let run (cctxt : #Proto_alpha.full) ?max_priority ?min_date delegates =
|
let run (cctxt : #Proto_alpha.full) ?max_priority ?min_date ~context_path delegates =
|
||||||
Client_baking_blocks.monitor_heads
|
Client_baking_blocks.monitor_heads
|
||||||
cctxt `Main >>=? fun block_stream ->
|
cctxt `Main >>=? fun block_stream ->
|
||||||
Client_baking_forge.create cctxt
|
Client_baking_forge.create cctxt
|
||||||
?max_priority delegates block_stream >>=? fun () ->
|
?max_priority ~context_path delegates block_stream >>=? fun () ->
|
||||||
ignore min_date;
|
ignore min_date;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ module Baker : sig
|
|||||||
#Proto_alpha.full ->
|
#Proto_alpha.full ->
|
||||||
?max_priority: int ->
|
?max_priority: int ->
|
||||||
?min_date: Time.t ->
|
?min_date: Time.t ->
|
||||||
|
context_path: string ->
|
||||||
public_key_hash list -> unit tzresult Lwt.t
|
public_key_hash list -> unit tzresult Lwt.t
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,14 +54,18 @@ let baker_commands () =
|
|||||||
title = "Commands related to the baker daemon." }
|
title = "Commands related to the baker daemon." }
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
command ~group ~desc: "Launch a daemon that handles delegate operations."
|
command ~group ~desc: "Launch the baker daemon."
|
||||||
(args1 max_priority_arg)
|
(args1 max_priority_arg)
|
||||||
(prefixes [ "launch" ]
|
(prefixes [ "launch" ; "with" ; "context" ]
|
||||||
|
@@ string
|
||||||
|
~name:"Context path"
|
||||||
|
~desc:"Path to the shell context"
|
||||||
@@ seq_of_param Client_keys.Public_key_hash.alias_param)
|
@@ seq_of_param Client_keys.Public_key_hash.alias_param)
|
||||||
(fun max_priority delegates cctxt ->
|
(fun max_priority context_path delegates cctxt ->
|
||||||
Client_daemon.Baker.run cctxt
|
Client_daemon.Baker.run cctxt
|
||||||
?max_priority
|
?max_priority
|
||||||
~min_date:((Time.add (Time.now ()) (Int64.neg 1800L)))
|
~min_date:((Time.add (Time.now ()) (Int64.neg 1800L)))
|
||||||
|
~context_path
|
||||||
(List.map snd delegates)
|
(List.map snd delegates)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
tezos-client-base
|
tezos-client-base
|
||||||
tezos-client-alpha
|
tezos-client-alpha
|
||||||
tezos-client-commands
|
tezos-client-commands
|
||||||
|
tezos-storage
|
||||||
tezos-rpc))
|
tezos-rpc))
|
||||||
(library_flags (:standard -linkall))
|
(library_flags (:standard -linkall))
|
||||||
(modules (:standard \
|
(modules (:standard \
|
||||||
@ -22,6 +23,7 @@
|
|||||||
-open Tezos_client_base
|
-open Tezos_client_base
|
||||||
-open Tezos_client_alpha
|
-open Tezos_client_alpha
|
||||||
-open Tezos_client_commands
|
-open Tezos_client_commands
|
||||||
|
-open Tezos_storage
|
||||||
-open Tezos_rpc))))
|
-open Tezos_rpc))))
|
||||||
|
|
||||||
(library
|
(library
|
||||||
|
Loading…
Reference in New Issue
Block a user