Alpha/RPC: use query string for delegation rights
This commit is contained in:
parent
7b758dbca8
commit
482dbb116c
@ -30,13 +30,12 @@ let commands () =
|
|||||||
iter_s (fun d -> Client_keys.get_key cctxt d >>|? fun _ -> ()) delegates >>=? fun () ->
|
iter_s (fun d -> Client_keys.get_key cctxt d >>|? fun _ -> ()) delegates >>=? fun () ->
|
||||||
run_daemon cctxt ?max_priority ~endorsement_delay ~endorsement ~baking ~denunciation delegates) ;
|
run_daemon cctxt ?max_priority ~endorsement_delay ~endorsement ~baking ~denunciation delegates) ;
|
||||||
command ~group ~desc: "Forge and inject an endorsement operation."
|
command ~group ~desc: "Forge and inject an endorsement operation."
|
||||||
(args1 max_priority_arg)
|
no_options
|
||||||
(prefixes [ "endorse"; "for" ]
|
(prefixes [ "endorse"; "for" ]
|
||||||
@@ Client_keys.Public_key_hash.source_param
|
@@ Client_keys.Public_key_hash.source_param
|
||||||
~name:"baker" ~desc: "name of the delegate owning the endorsement right"
|
~name:"baker" ~desc: "name of the delegate owning the endorsement right"
|
||||||
@@ stop)
|
@@ stop)
|
||||||
(fun max_priority delegate cctxt ->
|
(fun () delegate cctxt -> endorse_block cctxt delegate) ;
|
||||||
endorse_block cctxt ?max_priority delegate) ;
|
|
||||||
command ~group ~desc: "Forge and inject block using the delegate rights."
|
command ~group ~desc: "Forge and inject block using the delegate rights."
|
||||||
(args4 max_priority_arg force_switch
|
(args4 max_priority_arg force_switch
|
||||||
free_baking_switch minimal_timestamp_switch)
|
free_baking_switch minimal_timestamp_switch)
|
||||||
|
@ -82,14 +82,14 @@ end = struct
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let get_signing_slots cctxt ?max_priority ?(chain = `Main) block delegate level =
|
let get_signing_slots cctxt ?(chain = `Main) block delegate level =
|
||||||
Alpha_services.Delegate.Endorser.rights_for_delegate cctxt
|
Alpha_services.Delegate.Endorsing_rights.get cctxt
|
||||||
?max_priority ~first_level:level ~last_level:level
|
~levels:[level]
|
||||||
(chain, block) delegate >>=? fun possibilities ->
|
~delegates:[delegate]
|
||||||
let slots =
|
(chain, block) >>=? fun possibilities ->
|
||||||
List.map (fun (_,slot) -> slot)
|
match possibilities with
|
||||||
@@ List.filter (fun (l, _) -> l = level) possibilities in
|
| [{ slots }] -> return slots
|
||||||
return slots
|
| _ -> return []
|
||||||
|
|
||||||
let inject_endorsement
|
let inject_endorsement
|
||||||
(cctxt : #Proto_alpha.full)
|
(cctxt : #Proto_alpha.full)
|
||||||
@ -130,7 +130,7 @@ let check_endorsement cctxt level slot =
|
|||||||
|
|
||||||
let forge_endorsement (cctxt : #Proto_alpha.full)
|
let forge_endorsement (cctxt : #Proto_alpha.full)
|
||||||
?(chain = `Main) block
|
?(chain = `Main) block
|
||||||
~src_sk ?slots ?max_priority src_pk =
|
~src_sk ?slots src_pk =
|
||||||
let src_pkh = Signature.Public_key.hash src_pk in
|
let src_pkh = Signature.Public_key.hash src_pk in
|
||||||
Block_services.Metadata.protocol_data
|
Block_services.Metadata.protocol_data
|
||||||
cctxt ~chain ~block () >>=? fun { level = { level } } ->
|
cctxt ~chain ~block () >>=? fun { level = { level } } ->
|
||||||
@ -139,7 +139,7 @@ let forge_endorsement (cctxt : #Proto_alpha.full)
|
|||||||
| Some slots -> return slots
|
| Some slots -> return slots
|
||||||
| None ->
|
| None ->
|
||||||
get_signing_slots
|
get_signing_slots
|
||||||
cctxt ?max_priority ~chain block src_pkh level >>=? function
|
cctxt ~chain block src_pkh level >>=? function
|
||||||
| [] -> cctxt#error "No slot found at level %a" Raw_level.pp level
|
| [] -> cctxt#error "No slot found at level %a" Raw_level.pp level
|
||||||
| slots -> return slots
|
| slots -> return slots
|
||||||
end >>=? fun slots ->
|
end >>=? fun slots ->
|
||||||
|
@ -16,7 +16,6 @@ val forge_endorsement:
|
|||||||
Block_services.block ->
|
Block_services.block ->
|
||||||
src_sk:Client_keys.sk_uri ->
|
src_sk:Client_keys.sk_uri ->
|
||||||
?slots:int list ->
|
?slots:int list ->
|
||||||
?max_priority:int ->
|
|
||||||
public_key ->
|
public_key ->
|
||||||
Operation_hash.t tzresult Lwt.t
|
Operation_hash.t tzresult Lwt.t
|
||||||
|
|
||||||
|
@ -153,15 +153,15 @@ let forge_block cctxt ?(chain = `Main) block
|
|||||||
| `Set priority -> begin
|
| `Set priority -> begin
|
||||||
Alpha_services.Helpers.minimal_time
|
Alpha_services.Helpers.minimal_time
|
||||||
cctxt (chain, block) ~priority >>=? fun time ->
|
cctxt (chain, block) ~priority >>=? fun time ->
|
||||||
return (priority, time)
|
return (priority, Some time)
|
||||||
end
|
end
|
||||||
| `Auto (src_pkh, max_priority, free_baking) ->
|
| `Auto (src_pkh, max_priority, free_baking) ->
|
||||||
Alpha_services.Helpers.next_level cctxt (chain, block) >>=? fun { level } ->
|
Alpha_services.Helpers.next_level cctxt (chain, block) >>=? fun { level } ->
|
||||||
Alpha_services.Delegate.Baker.rights_for_delegate cctxt
|
Alpha_services.Delegate.Baking_rights.get cctxt
|
||||||
?max_priority
|
?max_priority
|
||||||
~first_level:level
|
~levels:[level]
|
||||||
~last_level:level
|
~delegates:[src_pkh]
|
||||||
(chain, block) src_pkh >>=? fun possibilities ->
|
(chain, block) >>=? fun possibilities ->
|
||||||
try
|
try
|
||||||
begin
|
begin
|
||||||
if free_baking then
|
if free_baking then
|
||||||
@ -169,8 +169,12 @@ let forge_block cctxt ?(chain = `Main) block
|
|||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
end >>=? fun min_prio ->
|
end >>=? fun min_prio ->
|
||||||
let _, prio, time =
|
let { Alpha_services.Delegate.Baking_rights.priority = prio ;
|
||||||
List.find (fun (l,p,_) -> l = level && p >= min_prio) possibilities in
|
timestamp = time } =
|
||||||
|
List.find
|
||||||
|
(fun (p : Alpha_services.Delegate.Baking_rights.t) ->
|
||||||
|
p.level = level && p.priority >= min_prio)
|
||||||
|
possibilities in
|
||||||
return (prio, time)
|
return (prio, time)
|
||||||
with Not_found ->
|
with Not_found ->
|
||||||
failwith "No slot found at level %a" Raw_level.pp level
|
failwith "No slot found at level %a" Raw_level.pp level
|
||||||
@ -179,8 +183,10 @@ let forge_block cctxt ?(chain = `Main) block
|
|||||||
(* Raw_level.pp level priority >>= fun () -> *)
|
(* Raw_level.pp level priority >>= fun () -> *)
|
||||||
begin
|
begin
|
||||||
match timestamp, minimal_timestamp with
|
match timestamp, minimal_timestamp with
|
||||||
| None, timestamp -> return timestamp
|
| None, None -> return (Time.now ())
|
||||||
| Some timestamp, minimal_timestamp ->
|
| None, Some timestamp -> return timestamp
|
||||||
|
| Some timestamp, None -> return timestamp
|
||||||
|
| Some timestamp, Some minimal_timestamp ->
|
||||||
if timestamp < minimal_timestamp then
|
if timestamp < minimal_timestamp then
|
||||||
failwith
|
failwith
|
||||||
"Proposed timestamp %a is earlier than minimal timestamp %a"
|
"Proposed timestamp %a is earlier than minimal timestamp %a"
|
||||||
@ -325,29 +331,22 @@ let get_baking_slot cctxt
|
|||||||
let chain = `Hash bi.chain_id in
|
let chain = `Hash bi.chain_id in
|
||||||
let block = `Hash (bi.hash, 0) in
|
let block = `Hash (bi.hash, 0) in
|
||||||
let level = Raw_level.succ bi.level.level in
|
let level = Raw_level.succ bi.level.level in
|
||||||
Lwt_list.filter_map_p
|
Alpha_services.Delegate.Baking_rights.get cctxt
|
||||||
(fun delegate ->
|
|
||||||
Alpha_services.Delegate.Baker.rights_for_delegate cctxt
|
|
||||||
?max_priority
|
?max_priority
|
||||||
~first_level:level
|
~levels:[level]
|
||||||
~last_level:level
|
~delegates
|
||||||
(chain, block) delegate >>= function
|
(chain, block) >>= function
|
||||||
| Error errs ->
|
| Error errs ->
|
||||||
log_error "Error while fetching baking possibilities:\n%a"
|
log_error "Error while fetching baking possibilities:\n%a"
|
||||||
pp_print_error errs ;
|
pp_print_error errs ;
|
||||||
Lwt.return_none
|
Lwt.return_none
|
||||||
| Ok slots ->
|
| Ok [] ->
|
||||||
let convert = fun (_lvl, slot, timestamp) ->
|
Lwt.return_none
|
||||||
(timestamp, (bi, slot, delegate)) in
|
| Ok ((slot : Alpha_services.Delegate.Baking_rights.t) :: _) ->
|
||||||
Lwt.return (Some (List.map convert slots)))
|
match slot.timestamp with
|
||||||
delegates >>= fun slots ->
|
| None -> Lwt.return_none
|
||||||
let sorted_slots =
|
| Some timestamp ->
|
||||||
List.sort
|
Lwt.return_some (timestamp, (bi, slot.priority, slot.delegate))
|
||||||
(fun (t1,_) (t2,_) -> Time.compare t1 t2)
|
|
||||||
(List.flatten slots) in
|
|
||||||
match sorted_slots with
|
|
||||||
| [] -> Lwt.return None
|
|
||||||
| slot :: _ -> Lwt.return (Some slot)
|
|
||||||
|
|
||||||
let rec insert_baking_slot slot = function
|
let rec insert_baking_slot slot = function
|
||||||
| [] -> [slot]
|
| [] -> [slot]
|
||||||
|
@ -44,10 +44,10 @@ let bake_block (cctxt : #Proto_alpha.full)
|
|||||||
cctxt#message "Injected block %a" Block_hash.pp_short block_hash >>= fun () ->
|
cctxt#message "Injected block %a" Block_hash.pp_short block_hash >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let endorse_block cctxt ?max_priority delegate =
|
let endorse_block cctxt delegate =
|
||||||
Client_keys.get_key cctxt delegate >>=? fun (_src_name, src_pk, src_sk) ->
|
Client_keys.get_key cctxt delegate >>=? fun (_src_name, src_pk, src_sk) ->
|
||||||
Client_baking_endorsement.forge_endorsement cctxt
|
Client_baking_endorsement.forge_endorsement cctxt
|
||||||
cctxt#block ?max_priority ~src_sk src_pk >>=? fun oph ->
|
cctxt#block ~src_sk src_pk >>=? fun oph ->
|
||||||
cctxt#answer "Operation successfully injected in the node." >>= fun () ->
|
cctxt#answer "Operation successfully injected in the node." >>= fun () ->
|
||||||
cctxt#answer "Operation hash is '%a'." Operation_hash.pp oph >>= fun () ->
|
cctxt#answer "Operation hash is '%a'." Operation_hash.pp oph >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
@ -26,7 +26,6 @@ val bake_block:
|
|||||||
(** Endorse a block *)
|
(** Endorse a block *)
|
||||||
val endorse_block:
|
val endorse_block:
|
||||||
#Proto_alpha.full ->
|
#Proto_alpha.full ->
|
||||||
?max_priority:int ->
|
|
||||||
Client_keys.Public_key_hash.t ->
|
Client_keys.Public_key_hash.t ->
|
||||||
unit Error_monad.tzresult Lwt.t
|
unit Error_monad.tzresult Lwt.t
|
||||||
|
|
||||||
|
@ -560,17 +560,14 @@ module Endorse = struct
|
|||||||
sign ~watermark:Endorsement src_sk shell contents
|
sign ~watermark:Endorsement src_sk shell contents
|
||||||
|
|
||||||
let signing_slots
|
let signing_slots
|
||||||
?(max_priority = 1024)
|
|
||||||
block
|
block
|
||||||
delegate
|
delegate
|
||||||
level =
|
level =
|
||||||
Alpha_services.Delegate.Endorser.rights_for_delegate
|
Alpha_services.Delegate.Endorsing_rights.get
|
||||||
!rpc_ctxt ~max_priority ~first_level:level ~last_level:level
|
!rpc_ctxt ~delegates:[delegate] ~levels:[level]
|
||||||
(`Main, block) delegate >>=? fun possibilities ->
|
(`Main, block) >>=? function
|
||||||
let slots =
|
| [{ slots }] -> return slots
|
||||||
List.map (fun (_,slot) -> slot)
|
| _ -> return []
|
||||||
@@ List.filter (fun (l, _) -> l = level) possibilities in
|
|
||||||
return slots
|
|
||||||
|
|
||||||
let endorse
|
let endorse
|
||||||
?slot
|
?slot
|
||||||
@ -596,15 +593,15 @@ module Endorse = struct
|
|||||||
(* FIXME @vb: I don't understand this function, copied from @cago. *)
|
(* FIXME @vb: I don't understand this function, copied from @cago. *)
|
||||||
let endorsers_list block =
|
let endorsers_list block =
|
||||||
let get_endorser_list result (account : Account.t) level block =
|
let get_endorser_list result (account : Account.t) level block =
|
||||||
Alpha_services.Delegate.Endorser.rights_for_delegate
|
Alpha_services.Delegate.Endorsing_rights.get
|
||||||
!rpc_ctxt (`Main, block) account.pkh
|
!rpc_ctxt (`Main, block)
|
||||||
~max_priority:16
|
~delegates:[account.pkh]
|
||||||
~first_level:level
|
~levels:[level] >>|? function
|
||||||
~last_level:level >>|? fun slots ->
|
| [{ slots }] ->
|
||||||
List.iter (fun (_,slot) -> result.(slot) <- account) slots
|
List.iter (fun s -> result.(s) <- account) slots
|
||||||
in
|
| _ -> () in
|
||||||
let { Account.b1 ; b2 ; b3 ; b4 ; b5 } = Account.bootstrap_accounts in
|
let { Account.b1 ; b2 ; b3 ; b4 ; b5 } = Account.bootstrap_accounts in
|
||||||
let result = Array.make 16 b1 in
|
let result = Array.make 32 b1 in
|
||||||
Block_services.Metadata.protocol_data
|
Block_services.Metadata.protocol_data
|
||||||
!rpc_ctxt ~chain:`Main ~block () >>=? fun { level } ->
|
!rpc_ctxt ~chain:`Main ~block () >>=? fun { level } ->
|
||||||
let level = level.level in
|
let level = level.level in
|
||||||
@ -616,18 +613,18 @@ module Endorse = struct
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
let endorsement_rights
|
let endorsement_rights
|
||||||
?(max_priority = 1024)
|
|
||||||
(contract : Account.t) block =
|
(contract : Account.t) block =
|
||||||
Block_services.Metadata.protocol_data
|
Block_services.Metadata.protocol_data
|
||||||
!rpc_ctxt ~chain:`Main ~block () >>=? fun { level } ->
|
!rpc_ctxt ~chain:`Main ~block () >>=? fun { level } ->
|
||||||
let level = level.level in
|
let level = level.level in
|
||||||
let delegate = contract.pkh in
|
let delegate = contract.pkh in
|
||||||
Alpha_services.Delegate.Endorser.rights_for_delegate
|
Alpha_services.Delegate.Endorsing_rights.get
|
||||||
!rpc_ctxt
|
!rpc_ctxt
|
||||||
~max_priority
|
~levels:[level]
|
||||||
~first_level:level
|
~delegates:[delegate]
|
||||||
~last_level:level
|
(`Main, block) >>=? function
|
||||||
(`Main, block) delegate
|
| [{ level ; slots }] -> return (List.map (fun s -> (level, s)) slots)
|
||||||
|
| _ -> return []
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -122,7 +122,6 @@ module Endorse : sig
|
|||||||
Account.t array tzresult Lwt.t
|
Account.t array tzresult Lwt.t
|
||||||
|
|
||||||
val endorsement_rights :
|
val endorsement_rights :
|
||||||
?max_priority:int ->
|
|
||||||
Account.t ->
|
Account.t ->
|
||||||
Block_services.block ->
|
Block_services.block ->
|
||||||
(Raw_level.t * int) list tzresult Lwt.t
|
(Raw_level.t * int) list tzresult Lwt.t
|
||||||
|
@ -352,9 +352,10 @@ let apply_consensus_operation_content ctxt
|
|||||||
Operation.check_signature delegate operation >>=? fun () ->
|
Operation.check_signature delegate operation >>=? fun () ->
|
||||||
let delegate = Signature.Public_key.hash delegate in
|
let delegate = Signature.Public_key.hash delegate in
|
||||||
let ctxt = Fitness.increase ~gap:(List.length slots) ctxt in
|
let ctxt = Fitness.increase ~gap:(List.length slots) ctxt in
|
||||||
Baking.freeze_endorsement_deposit ctxt delegate >>=? fun ctxt ->
|
Baking.freeze_endorsement_deposit
|
||||||
|
ctxt delegate (List.length slots) >>=? fun ctxt ->
|
||||||
Global.get_last_block_priority ctxt >>=? fun block_priority ->
|
Global.get_last_block_priority ctxt >>=? fun block_priority ->
|
||||||
Baking.endorsement_reward ctxt ~block_priority >>=? fun reward ->
|
Baking.endorsement_reward ctxt ~block_priority (List.length slots) >>=? fun reward ->
|
||||||
Delegate.freeze_rewards ctxt delegate reward >>=? fun ctxt ->
|
Delegate.freeze_rewards ctxt delegate reward >>=? fun ctxt ->
|
||||||
return (ctxt, Endorsements_result (delegate, slots))
|
return (ctxt, Endorsements_result (delegate, slots))
|
||||||
|
|
||||||
|
@ -151,6 +151,18 @@ let minimal_time c priority pred_timestamp =
|
|||||||
(cumsum_time_between_blocks
|
(cumsum_time_between_blocks
|
||||||
pred_timestamp (Constants.time_between_blocks c) (Int32.succ priority))
|
pred_timestamp (Constants.time_between_blocks c) (Int32.succ priority))
|
||||||
|
|
||||||
|
let earlier_predecessor_timestamp ctxt level =
|
||||||
|
let current = Level.current ctxt in
|
||||||
|
let current_timestamp = Timestamp.current ctxt in
|
||||||
|
let gap = Level.diff level current in
|
||||||
|
let step = List.hd (Constants.time_between_blocks ctxt) in
|
||||||
|
if Compare.Int32.(gap < 1l) then
|
||||||
|
failwith "Baking.earlier_block_timestamp: past block."
|
||||||
|
else
|
||||||
|
Lwt.return (Period.mult (Int32.pred gap) step) >>=? fun delay ->
|
||||||
|
Lwt.return Timestamp.(current_timestamp +? delay) >>=? fun result ->
|
||||||
|
return result
|
||||||
|
|
||||||
let freeze_baking_deposit ctxt { Block_header.priority ; _ } delegate =
|
let freeze_baking_deposit ctxt { Block_header.priority ; _ } delegate =
|
||||||
if Compare.Int.(priority >= Constants.first_free_baking_slot ctxt)
|
if Compare.Int.(priority >= Constants.first_free_baking_slot ctxt)
|
||||||
then return (ctxt, Tez.zero)
|
then return (ctxt, Tez.zero)
|
||||||
@ -160,8 +172,9 @@ let freeze_baking_deposit ctxt { Block_header.priority ; _ } delegate =
|
|||||||
|> trace Cannot_freeze_baking_deposit >>=? fun ctxt ->
|
|> trace Cannot_freeze_baking_deposit >>=? fun ctxt ->
|
||||||
return (ctxt, deposit)
|
return (ctxt, deposit)
|
||||||
|
|
||||||
let freeze_endorsement_deposit ctxt delegate =
|
let freeze_endorsement_deposit ctxt delegate n =
|
||||||
let deposit = Constants.endorsement_security_deposit ctxt in
|
let deposit = Constants.endorsement_security_deposit ctxt in
|
||||||
|
Lwt.return (Tez.(deposit *? Int64.of_int n)) >>=? fun deposit ->
|
||||||
Delegate.freeze_deposit ctxt delegate deposit
|
Delegate.freeze_deposit ctxt delegate deposit
|
||||||
|> trace Cannot_freeze_endorsement_deposit
|
|> trace Cannot_freeze_endorsement_deposit
|
||||||
|
|
||||||
@ -196,11 +209,12 @@ let paying_priorities c =
|
|||||||
|
|
||||||
type error += Incorrect_priority
|
type error += Incorrect_priority
|
||||||
|
|
||||||
let endorsement_reward ctxt ~block_priority:prio =
|
let endorsement_reward ctxt ~block_priority:prio n =
|
||||||
if Compare.Int.(prio >= 0)
|
if Compare.Int.(prio >= 0)
|
||||||
then
|
then
|
||||||
Lwt.return
|
Lwt.return
|
||||||
Tez.(Constants.endorsement_reward ctxt /? (Int64.(succ (of_int prio))))
|
Tez.(Constants.endorsement_reward ctxt /? (Int64.(succ (of_int prio)))) >>=? fun tez ->
|
||||||
|
Lwt.return Tez.(tez *? Int64.of_int n)
|
||||||
else fail Incorrect_priority
|
else fail Incorrect_priority
|
||||||
|
|
||||||
let baking_priorities c level =
|
let baking_priorities c level =
|
||||||
|
@ -50,7 +50,7 @@ val freeze_baking_deposit:
|
|||||||
Raise an error if the baker account does not have enough
|
Raise an error if the baker account does not have enough
|
||||||
funds to claim endorsement rights *)
|
funds to claim endorsement rights *)
|
||||||
val freeze_endorsement_deposit:
|
val freeze_endorsement_deposit:
|
||||||
context -> public_key_hash -> context tzresult Lwt.t
|
context -> public_key_hash -> int -> context tzresult Lwt.t
|
||||||
|
|
||||||
(** [check_baking_rights ctxt block pred_timestamp] verifies that:
|
(** [check_baking_rights ctxt block pred_timestamp] verifies that:
|
||||||
* the contract that owned the roll at cycle start has the block signer as delegate.
|
* the contract that owned the roll at cycle start has the block signer as delegate.
|
||||||
@ -69,7 +69,7 @@ val check_endorsements_rights:
|
|||||||
context -> Level.t -> int list -> public_key tzresult Lwt.t
|
context -> Level.t -> int list -> public_key tzresult Lwt.t
|
||||||
|
|
||||||
(** Returns the endorsement reward calculated w.r.t a given priotiry. *)
|
(** Returns the endorsement reward calculated w.r.t a given priotiry. *)
|
||||||
val endorsement_reward: context -> block_priority:int -> Tez.t tzresult Lwt.t
|
val endorsement_reward: context -> block_priority:int -> int -> Tez.t tzresult Lwt.t
|
||||||
|
|
||||||
(** [baking_priorities ctxt level] is the lazy list of contract's
|
(** [baking_priorities ctxt level] is the lazy list of contract's
|
||||||
public key hashes that are allowed to bake for [level]. *)
|
public key hashes that are allowed to bake for [level]. *)
|
||||||
@ -120,3 +120,5 @@ val check_fitness_gap:
|
|||||||
context -> Block_header.t -> unit tzresult Lwt.t
|
context -> Block_header.t -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val dawn_of_a_new_cycle: context -> Cycle.t option tzresult Lwt.t
|
val dawn_of_a_new_cycle: context -> Cycle.t option tzresult Lwt.t
|
||||||
|
|
||||||
|
val earlier_predecessor_timestamp: context -> Level.t -> Timestamp.t tzresult Lwt.t
|
||||||
|
@ -9,13 +9,6 @@
|
|||||||
|
|
||||||
open Alpha_context
|
open Alpha_context
|
||||||
|
|
||||||
let slots_range_encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
(obj3
|
|
||||||
(opt "max_priority" int31)
|
|
||||||
(opt "first_level" Raw_level.encoding)
|
|
||||||
(opt "last_level" Raw_level.encoding))
|
|
||||||
|
|
||||||
type info = {
|
type info = {
|
||||||
balance: Tez.t ;
|
balance: Tez.t ;
|
||||||
frozen_balance: Tez.t ;
|
frozen_balance: Tez.t ;
|
||||||
@ -230,313 +223,264 @@ let deactivated ctxt block pkh =
|
|||||||
let grace_period ctxt block pkh =
|
let grace_period ctxt block pkh =
|
||||||
RPC_context.make_call1 S.grace_period ctxt block pkh () ()
|
RPC_context.make_call1 S.grace_period ctxt block pkh () ()
|
||||||
|
|
||||||
|
let requested_levels ~default ctxt cycles levels =
|
||||||
module Baker = struct
|
match levels, cycles with
|
||||||
|
| [], [] ->
|
||||||
module S = struct
|
return [default]
|
||||||
|
| levels, cycles ->
|
||||||
open Data_encoding
|
(* explicitly fail when requested levels or cycle are in the past...
|
||||||
|
or too far in the future... *)
|
||||||
let custom_root =
|
(* check_levels levels >>=? fun () -> *)
|
||||||
RPC_path.(open_root / "helpers" / "rights" / "baking")
|
(* check_cycles levels >>=? fun () -> *)
|
||||||
|
let levels =
|
||||||
let slot_encoding =
|
List.sort_uniq
|
||||||
(obj3
|
Level.compare
|
||||||
(req "level" Raw_level.encoding)
|
(List.concat (List.map (Level.from_raw ctxt) levels ::
|
||||||
(req "priority" int31)
|
List.map (Level.levels_in_cycle ctxt) cycles)) in
|
||||||
(req "timestamp" Timestamp.encoding))
|
map_p
|
||||||
|
(fun level ->
|
||||||
let rights =
|
|
||||||
RPC_service.post_service
|
|
||||||
~description:
|
|
||||||
"List delegates allowed to bake for the next level, \
|
|
||||||
ordered by priority."
|
|
||||||
~query: RPC_query.empty
|
|
||||||
~input: (obj1 (opt "max_priority" int31))
|
|
||||||
~output: (obj2
|
|
||||||
(req "level" Raw_level.encoding)
|
|
||||||
(req "baking_rights"
|
|
||||||
(list
|
|
||||||
(obj2
|
|
||||||
(req "delegate" Signature.Public_key_hash.encoding)
|
|
||||||
(req "timestamp" Timestamp.encoding)))))
|
|
||||||
custom_root
|
|
||||||
|
|
||||||
let rights_for_level =
|
|
||||||
RPC_service.post_service
|
|
||||||
~description:
|
|
||||||
"List delegates allowed to bake for a given level, \
|
|
||||||
ordered by priority."
|
|
||||||
~query: RPC_query.empty
|
|
||||||
~input: (obj1 (opt "max_priority" int31))
|
|
||||||
~output: (obj2
|
|
||||||
(req "level" Raw_level.encoding)
|
|
||||||
(req "delegates"
|
|
||||||
(list Signature.Public_key_hash.encoding)))
|
|
||||||
RPC_path.(custom_root / "level" /: Raw_level.arg)
|
|
||||||
|
|
||||||
(* let levels = *)
|
|
||||||
(* RPC_service.post_service *)
|
|
||||||
(* ~description: *)
|
|
||||||
(* "List level for which we might computed baking rights." *)
|
|
||||||
(* ~query: RPC_query.empty *)
|
|
||||||
(* ~input: empty *)
|
|
||||||
(* ~output: (obj1 (req "levels" (list Raw_level.encoding))) *)
|
|
||||||
(* RPC_path.(custom_root / "level") *)
|
|
||||||
|
|
||||||
let rights_for_delegate =
|
|
||||||
RPC_service.post_service
|
|
||||||
~description: "Future baking rights for a given delegate."
|
|
||||||
~query: RPC_query.empty
|
|
||||||
~input: slots_range_encoding
|
|
||||||
~output: (Data_encoding.list slot_encoding)
|
|
||||||
RPC_path.(custom_root / "delegate" /: Signature.Public_key_hash.rpc_arg)
|
|
||||||
|
|
||||||
|
|
||||||
(* let delegates = *)
|
|
||||||
(* RPC_service.post_service *)
|
|
||||||
(* ~description: *)
|
|
||||||
(* "List delegates with baking rights." *)
|
|
||||||
(* ~query: RPC_query.empty *)
|
|
||||||
(* ~input: empty *)
|
|
||||||
(* ~output: (obj1 (req "delegates" *)
|
|
||||||
(* (list Signature.Public_key_hash.encoding))) *)
|
|
||||||
(* RPC_path.(custom_root / "delegate") *)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module I = struct
|
|
||||||
|
|
||||||
let default_max_baking_priority ctxt arg =
|
|
||||||
let default = Constants.first_free_baking_slot ctxt in
|
|
||||||
match arg with
|
|
||||||
| None -> 2 * default
|
|
||||||
| Some m -> m
|
|
||||||
|
|
||||||
let baking_rights_for_level ctxt level max =
|
|
||||||
let max = default_max_baking_priority ctxt max in
|
|
||||||
Baking.baking_priorities ctxt level >>=? fun contract_list ->
|
|
||||||
let rec loop l n =
|
|
||||||
match n with
|
|
||||||
| 0 -> return []
|
|
||||||
| n ->
|
|
||||||
let Misc.LCons (h, t) = l in
|
|
||||||
t () >>=? fun t ->
|
|
||||||
loop t (pred n) >>=? fun t ->
|
|
||||||
return (Signature.Public_key.hash h :: t)
|
|
||||||
in
|
|
||||||
loop contract_list max >>=? fun prio ->
|
|
||||||
return (level.level, prio)
|
|
||||||
|
|
||||||
let baking_rights ctxt () max =
|
|
||||||
let level = Level.succ ctxt (Level.current ctxt) in
|
|
||||||
baking_rights_for_level ctxt level max >>=? fun (raw_level, slots) ->
|
|
||||||
begin
|
|
||||||
Lwt_list.filter_map_p (fun x -> x) @@
|
|
||||||
List.mapi
|
|
||||||
(fun prio c ->
|
|
||||||
let timestamp = Timestamp.current ctxt in
|
|
||||||
Baking.minimal_time ctxt prio timestamp >>= function
|
|
||||||
| Error _ -> Lwt.return None
|
|
||||||
| Ok minimal_timestamp -> Lwt.return (Some (c, minimal_timestamp)))
|
|
||||||
slots
|
|
||||||
end >>= fun timed_slots ->
|
|
||||||
return (raw_level, timed_slots)
|
|
||||||
|
|
||||||
let baking_rights_for_delegate
|
|
||||||
ctxt contract () (max_priority, min_level, max_level) =
|
|
||||||
let max_priority = default_max_baking_priority ctxt max_priority in
|
|
||||||
let current_level = Level.succ ctxt (Level.current ctxt) in
|
|
||||||
let min_level = match min_level with
|
|
||||||
| None -> current_level
|
|
||||||
| Some l -> Level.from_raw ctxt l in
|
|
||||||
let max_level =
|
|
||||||
match max_level with
|
|
||||||
| Some max_level -> Level.from_raw ctxt max_level
|
|
||||||
| None ->
|
|
||||||
Level.last_level_in_cycle ctxt @@
|
|
||||||
current_level.cycle in
|
|
||||||
let rec loop level =
|
|
||||||
if Level.(>) level max_level
|
|
||||||
then return []
|
|
||||||
else
|
|
||||||
loop (Level.succ ctxt level) >>=? fun t ->
|
|
||||||
Baking.first_baking_priorities
|
|
||||||
ctxt ~max_priority contract level >>=? fun priorities ->
|
|
||||||
let raw_level = level.level in
|
|
||||||
Error_monad.map_s
|
|
||||||
(fun priority ->
|
|
||||||
let timestamp = Timestamp.current ctxt in
|
|
||||||
Baking.minimal_time ctxt priority timestamp >>=? fun time ->
|
|
||||||
return (raw_level, priority, time))
|
|
||||||
priorities >>=? fun priorities ->
|
|
||||||
return (priorities @ t)
|
|
||||||
in
|
|
||||||
loop min_level
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
let () =
|
|
||||||
let open Services_registration in
|
|
||||||
register0 S.rights I.baking_rights ;
|
|
||||||
register1 S.rights_for_level begin fun ctxt raw_level () max ->
|
|
||||||
let level = Level.from_raw ctxt raw_level in
|
|
||||||
I.baking_rights_for_level ctxt level max
|
|
||||||
end;
|
|
||||||
register1 S.rights_for_delegate I.baking_rights_for_delegate
|
|
||||||
|
|
||||||
let rights ctxt ?max_priority block =
|
|
||||||
RPC_context.make_call0 S.rights ctxt block () max_priority
|
|
||||||
|
|
||||||
let rights_for_level ctxt ?max_priority block level =
|
|
||||||
RPC_context.make_call1 S.rights_for_level ctxt block level () max_priority
|
|
||||||
|
|
||||||
let rights_for_delegate ctxt ?max_priority ?first_level ?last_level block delegate =
|
|
||||||
RPC_context.make_call1 S.rights_for_delegate ctxt block delegate ()
|
|
||||||
(max_priority, first_level, last_level)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Endorser = struct
|
|
||||||
|
|
||||||
module S = struct
|
|
||||||
|
|
||||||
open Data_encoding
|
|
||||||
|
|
||||||
let custom_root =
|
|
||||||
RPC_path.(open_root / "helpers" / "rights" / "endorsement")
|
|
||||||
|
|
||||||
let slot_encoding =
|
|
||||||
(obj2
|
|
||||||
(req "level" Raw_level.encoding)
|
|
||||||
(req "priority" int31))
|
|
||||||
|
|
||||||
let rights =
|
|
||||||
RPC_service.post_service
|
|
||||||
~description:
|
|
||||||
"List delegates allowed to endorse for the current block."
|
|
||||||
~query: RPC_query.empty
|
|
||||||
~input: (obj1 (opt "max_priority" int31))
|
|
||||||
~output: (obj2
|
|
||||||
(req "level" Raw_level.encoding)
|
|
||||||
(req "delegates"
|
|
||||||
(list Signature.Public_key_hash.encoding)))
|
|
||||||
custom_root
|
|
||||||
|
|
||||||
let rights_for_level =
|
|
||||||
RPC_service.post_service
|
|
||||||
~description:
|
|
||||||
"List delegates allowed to endorse blocks for a given level."
|
|
||||||
~query: RPC_query.empty
|
|
||||||
~input: (obj1 (opt "max_priority" int31))
|
|
||||||
~output: (obj2
|
|
||||||
(req "level" Raw_level.encoding)
|
|
||||||
(req "delegates"
|
|
||||||
(list Signature.Public_key_hash.encoding)))
|
|
||||||
RPC_path.(custom_root / "level" /: Raw_level.arg)
|
|
||||||
|
|
||||||
(* let levels = *)
|
|
||||||
(* RPC_service.post_service *)
|
|
||||||
(* ~description: *)
|
|
||||||
(* "List level for which we might computed endorsement rights." *)
|
|
||||||
(* ~query: RPC_query.empty *)
|
|
||||||
(* ~input: empty *)
|
|
||||||
(* ~output: (obj1 (req "levels" (list Raw_level.encoding))) *)
|
|
||||||
(* RPC_path.(custom_root / "level") *)
|
|
||||||
|
|
||||||
let rights_for_delegate =
|
|
||||||
RPC_service.post_service
|
|
||||||
~description: "Compute endorsement rights for a given delegate."
|
|
||||||
~query: RPC_query.empty
|
|
||||||
~input: slots_range_encoding
|
|
||||||
~output: (Data_encoding.list slot_encoding)
|
|
||||||
RPC_path.(custom_root / "delegate" /: Signature.Public_key_hash.rpc_arg)
|
|
||||||
|
|
||||||
(* let delegates = *)
|
|
||||||
(* RPC_service.post_service *)
|
|
||||||
(* ~description: *)
|
|
||||||
(* "List delegates with endorsement rights." *)
|
|
||||||
(* ~query: RPC_query.empty *)
|
|
||||||
(* ~input: empty *)
|
|
||||||
(* ~output: (obj1 (req "delegates" *)
|
|
||||||
(* (list Signature.Public_key_hash.encoding))) *)
|
|
||||||
(* RPC_path.(custom_root / "delegate") *)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module I = struct
|
|
||||||
|
|
||||||
let default_max_endorsement_priority ctxt arg =
|
|
||||||
let default = Constants.endorsers_per_block ctxt in
|
|
||||||
match arg with
|
|
||||||
| None -> default
|
|
||||||
| Some m -> m
|
|
||||||
|
|
||||||
let endorsement_rights ctxt level max =
|
|
||||||
let max = default_max_endorsement_priority ctxt max in
|
|
||||||
Baking.endorsement_priorities ctxt level >>=? fun contract_list ->
|
|
||||||
let rec loop l n =
|
|
||||||
match n with
|
|
||||||
| 0 -> return []
|
|
||||||
| n ->
|
|
||||||
let Misc.LCons (h, t) = l in
|
|
||||||
t () >>=? fun t ->
|
|
||||||
loop t (pred n) >>=? fun t ->
|
|
||||||
return (Signature.Public_key.hash h :: t)
|
|
||||||
in
|
|
||||||
loop contract_list max >>=? fun prio ->
|
|
||||||
return (level.level, prio)
|
|
||||||
|
|
||||||
let endorsement_rights_for_delegate
|
|
||||||
ctxt contract () (max_priority, min_level, max_level) =
|
|
||||||
let current_level = Level.current ctxt in
|
let current_level = Level.current ctxt in
|
||||||
let max_priority = default_max_endorsement_priority ctxt max_priority in
|
if Level.(level <= current_level) then
|
||||||
let min_level = match min_level with
|
return (level, None)
|
||||||
| None -> current_level
|
|
||||||
| Some l -> Level.from_raw ctxt l in
|
|
||||||
let max_level =
|
|
||||||
match max_level with
|
|
||||||
| None -> min_level
|
|
||||||
| Some l -> Level.from_raw ctxt l in
|
|
||||||
let rec loop level =
|
|
||||||
if Level.(>) level max_level
|
|
||||||
then return []
|
|
||||||
else
|
else
|
||||||
loop (Level.succ ctxt level) >>=? fun t ->
|
Baking.earlier_predecessor_timestamp
|
||||||
Baking.first_endorsement_slots
|
ctxt level >>=? fun timestamp ->
|
||||||
ctxt ~max_priority contract level >>=? fun slots ->
|
return (level, Some timestamp))
|
||||||
let raw_level = level.level in
|
levels
|
||||||
let slots = List.rev_map (fun slot -> (raw_level, slot)) slots in
|
|
||||||
return (List.rev_append slots t)
|
module Baking_rights = struct
|
||||||
in
|
|
||||||
loop min_level
|
type t = {
|
||||||
|
level: Raw_level.t ;
|
||||||
|
delegate: Signature.Public_key_hash.t ;
|
||||||
|
priority: int ;
|
||||||
|
timestamp: Timestamp.t option ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { level ; delegate ; priority ; timestamp } ->
|
||||||
|
(level, delegate, priority, timestamp))
|
||||||
|
(fun (level, delegate, priority, timestamp) ->
|
||||||
|
{ level ; delegate ; priority ; timestamp })
|
||||||
|
(obj4
|
||||||
|
(req "level" Raw_level.encoding)
|
||||||
|
(req "delegate" Signature.Public_key_hash.encoding)
|
||||||
|
(req "priority" uint16)
|
||||||
|
(opt "timestamp" Timestamp.encoding))
|
||||||
|
|
||||||
|
module S = struct
|
||||||
|
|
||||||
|
open Data_encoding
|
||||||
|
|
||||||
|
let custom_root =
|
||||||
|
RPC_path.(open_root / "helpers" / "baking_rights")
|
||||||
|
|
||||||
|
type baking_rights_query = {
|
||||||
|
levels: Raw_level.t list ;
|
||||||
|
cycles: Cycle.t list ;
|
||||||
|
delegates: Signature.Public_key_hash.t list ;
|
||||||
|
max_priority: int option ;
|
||||||
|
all: bool ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let baking_rights_query =
|
||||||
|
let open RPC_query in
|
||||||
|
query (fun levels cycles delegates max_priority all ->
|
||||||
|
{ levels ; cycles ; delegates ; max_priority ; all })
|
||||||
|
|+ multi_field "level" Raw_level.arg (fun t -> t.levels)
|
||||||
|
|+ multi_field "cycle" Cycle.arg (fun t -> t.cycles)
|
||||||
|
|+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> t.delegates)
|
||||||
|
|+ opt_field "max_priority" RPC_arg.int (fun t -> t.max_priority)
|
||||||
|
|+ flag "all" (fun t -> t.all)
|
||||||
|
|> seal
|
||||||
|
|
||||||
|
let baking_rights =
|
||||||
|
RPC_service.get_service
|
||||||
|
~description: "...FIXME..."
|
||||||
|
~query: baking_rights_query
|
||||||
|
~output: (list encoding)
|
||||||
|
custom_root
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let baking_priorities ctxt max_prio (level, pred_timestamp) =
|
||||||
|
Baking.baking_priorities ctxt level >>=? fun contract_list ->
|
||||||
|
let rec loop l acc priority =
|
||||||
|
if Compare.Int.(priority >= max_prio) then
|
||||||
|
return (List.rev acc)
|
||||||
|
else
|
||||||
|
let Misc.LCons (pk, next) = l in
|
||||||
|
let delegate = Signature.Public_key.hash pk in
|
||||||
|
begin
|
||||||
|
match pred_timestamp with
|
||||||
|
| None -> return None
|
||||||
|
| Some pred_timestamp ->
|
||||||
|
Baking.minimal_time ctxt priority pred_timestamp >>=? fun t ->
|
||||||
|
return (Some t)
|
||||||
|
end>>=? fun timestamp ->
|
||||||
|
let acc =
|
||||||
|
{ level = level.level ; delegate ; priority ; timestamp } :: acc in
|
||||||
|
next () >>=? fun l ->
|
||||||
|
loop l acc (priority+1) in
|
||||||
|
loop contract_list [] 0
|
||||||
|
|
||||||
|
let remove_duplicated_delegates rights =
|
||||||
|
List.rev @@ fst @@
|
||||||
|
List.fold_left
|
||||||
|
(fun (acc, previous) r ->
|
||||||
|
if Signature.Public_key_hash.Set.mem r.delegate previous then
|
||||||
|
(acc, previous)
|
||||||
|
else
|
||||||
|
(r :: acc,
|
||||||
|
Signature.Public_key_hash.Set.add r.delegate previous))
|
||||||
|
([], Signature.Public_key_hash.Set.empty)
|
||||||
|
rights
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
let open Services_registration in
|
let open Services_registration in
|
||||||
register0 S.rights begin fun ctxt () max ->
|
register0 S.baking_rights begin fun ctxt q () ->
|
||||||
let level = Level.current ctxt in
|
requested_levels
|
||||||
I.endorsement_rights ctxt level max
|
~default:
|
||||||
end ;
|
(Level.succ ctxt (Level.current ctxt), Some (Timestamp.current ctxt))
|
||||||
register1 S.rights_for_level begin fun ctxt raw_level () max ->
|
ctxt q.cycles q.levels >>=? fun levels ->
|
||||||
let level = Level.from_raw ctxt raw_level in
|
let max_priority =
|
||||||
I.endorsement_rights ctxt level max
|
match q.max_priority with
|
||||||
end ;
|
| None -> 64
|
||||||
register1 S.rights_for_delegate I.endorsement_rights_for_delegate
|
| Some max -> max in
|
||||||
|
map_p (baking_priorities ctxt max_priority) levels >>=? fun rights ->
|
||||||
|
let rights =
|
||||||
|
if q.all then
|
||||||
|
rights
|
||||||
|
else
|
||||||
|
List.map remove_duplicated_delegates rights in
|
||||||
|
let rights = List.concat rights in
|
||||||
|
match q.delegates with
|
||||||
|
| [] -> return rights
|
||||||
|
| _ :: _ as delegates ->
|
||||||
|
let is_requested p =
|
||||||
|
List.exists (Signature.Public_key_hash.equal p.delegate) delegates in
|
||||||
|
return (List.filter is_requested rights)
|
||||||
|
end
|
||||||
|
|
||||||
let rights ctxt ?max_priority block =
|
let get ctxt
|
||||||
RPC_context.make_call0 S.rights ctxt block () max_priority
|
?(levels = []) ?(cycles = []) ?(delegates = []) ?(all = false)
|
||||||
|
?max_priority block =
|
||||||
let rights_for_level ctxt ?max_priority block level =
|
RPC_context.make_call0 S.baking_rights ctxt block
|
||||||
RPC_context.make_call1 S.rights_for_level ctxt block level () max_priority
|
{ levels ; cycles ; delegates ; max_priority ; all }
|
||||||
|
()
|
||||||
let rights_for_delegate ctxt ?max_priority ?first_level ?last_level block delegate =
|
|
||||||
RPC_context.make_call1 S.rights_for_delegate ctxt block delegate ()
|
|
||||||
(max_priority, first_level, last_level)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Endorsing_rights = struct
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
level: Raw_level.t ;
|
||||||
|
delegate: Signature.Public_key_hash.t ;
|
||||||
|
slots: int list ;
|
||||||
|
estimated_time: Time.t option ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { level ; delegate ; slots ; estimated_time } ->
|
||||||
|
(level, delegate, slots, estimated_time))
|
||||||
|
(fun (level, delegate, slots, estimated_time) ->
|
||||||
|
{ level ; delegate ; slots ; estimated_time })
|
||||||
|
(obj4
|
||||||
|
(req "level" Raw_level.encoding)
|
||||||
|
(req "delegate" Signature.Public_key_hash.encoding)
|
||||||
|
(req "slots" (list uint16))
|
||||||
|
(opt "estimated_time" Timestamp.encoding))
|
||||||
|
|
||||||
|
module S = struct
|
||||||
|
|
||||||
|
open Data_encoding
|
||||||
|
|
||||||
|
let custom_root =
|
||||||
|
RPC_path.(open_root / "helpers" / "endorsing_rights")
|
||||||
|
|
||||||
|
type endorsing_rights_query = {
|
||||||
|
levels: Raw_level.t list ;
|
||||||
|
cycles: Cycle.t list ;
|
||||||
|
delegates: Signature.Public_key_hash.t list ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let endorsing_rights_query =
|
||||||
|
let open RPC_query in
|
||||||
|
query (fun levels cycles delegates ->
|
||||||
|
{ levels ; cycles ; delegates })
|
||||||
|
|+ multi_field "level" Raw_level.arg (fun t -> t.levels)
|
||||||
|
|+ multi_field "cycle" Cycle.arg (fun t -> t.cycles)
|
||||||
|
|+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> t.delegates)
|
||||||
|
|> seal
|
||||||
|
|
||||||
|
let endorsing_rights =
|
||||||
|
RPC_service.get_service
|
||||||
|
~description: "...FIXME..."
|
||||||
|
~query: endorsing_rights_query
|
||||||
|
~output: (list encoding)
|
||||||
|
custom_root
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
let endorsement_slots ctxt (level, estimated_time) =
|
||||||
|
let max_slot = Constants.endorsers_per_block ctxt in
|
||||||
|
Baking.endorsement_priorities ctxt level >>=? fun contract_list ->
|
||||||
|
let build (delegate, slots) = {
|
||||||
|
level = level.level ; delegate ; slots ; estimated_time
|
||||||
|
} in
|
||||||
|
let rec loop l map slot =
|
||||||
|
if Compare.Int.(slot >= max_slot) then
|
||||||
|
return (List.map build (Signature.Public_key_hash.Map.bindings map))
|
||||||
|
else
|
||||||
|
let Misc.LCons (pk, next) = l in
|
||||||
|
let delegate = Signature.Public_key.hash pk in
|
||||||
|
let slots =
|
||||||
|
match Signature.Public_key_hash.Map.find_opt delegate map with
|
||||||
|
| None -> [slot]
|
||||||
|
| Some slots -> slot :: slots in
|
||||||
|
let map = Signature.Public_key_hash.Map.add delegate slots map in
|
||||||
|
next () >>=? fun l ->
|
||||||
|
loop l map (slot+1) in
|
||||||
|
loop contract_list Signature.Public_key_hash.Map.empty 0
|
||||||
|
|
||||||
|
let () =
|
||||||
|
let open Services_registration in
|
||||||
|
register0 S.endorsing_rights begin fun ctxt q () ->
|
||||||
|
requested_levels
|
||||||
|
~default: (Level.current ctxt, Some (Timestamp.current ctxt))
|
||||||
|
ctxt q.cycles q.levels >>=? fun levels ->
|
||||||
|
map_p (endorsement_slots ctxt) levels >>=? fun rights ->
|
||||||
|
let rights = List.concat rights in
|
||||||
|
match q.delegates with
|
||||||
|
| [] -> return rights
|
||||||
|
| _ :: _ as delegates ->
|
||||||
|
let is_requested p =
|
||||||
|
List.exists (Signature.Public_key_hash.equal p.delegate) delegates in
|
||||||
|
return (List.filter is_requested rights)
|
||||||
|
end
|
||||||
|
|
||||||
|
let get ctxt
|
||||||
|
?(levels = []) ?(cycles = []) ?(delegates = []) block =
|
||||||
|
RPC_context.make_call0 S.endorsing_rights ctxt block
|
||||||
|
{ levels ; cycles ; delegates }
|
||||||
|
()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
let endorsement_rights ctxt level =
|
||||||
|
Endorsing_rights.endorsement_slots ctxt (level, None) >>=? fun l ->
|
||||||
|
return (List.map (fun { Endorsing_rights.delegate ; _ } -> delegate) l)
|
||||||
|
|
||||||
|
let baking_rights ctxt max_priority =
|
||||||
|
let max = match max_priority with None -> 64 | Some m -> m in
|
||||||
|
let level = Level.current ctxt in
|
||||||
|
Baking_rights.baking_priorities ctxt max (level, None) >>=? fun l ->
|
||||||
|
return (level.level,
|
||||||
|
List.map
|
||||||
|
(fun { Baking_rights.delegate ; timestamp ; _ } ->
|
||||||
|
(delegate, timestamp)) l)
|
||||||
|
|
||||||
let baking_rights = Baker.I.baking_rights
|
|
||||||
let endorsement_rights = Endorser.I.endorsement_rights
|
|
||||||
|
@ -68,50 +68,73 @@ val grace_period:
|
|||||||
Cycle.t shell_tzresult Lwt.t
|
Cycle.t shell_tzresult Lwt.t
|
||||||
|
|
||||||
|
|
||||||
module Baker : sig
|
module Baking_rights : sig
|
||||||
|
|
||||||
val rights:
|
type t = {
|
||||||
'a #RPC_context.simple -> ?max_priority:int -> 'a ->
|
level: Raw_level.t ;
|
||||||
(Raw_level.t * (Signature.Public_key_hash.t * Time.t) list) shell_tzresult Lwt.t
|
delegate: Signature.Public_key_hash.t ;
|
||||||
|
priority: int ;
|
||||||
|
timestamp: Timestamp.t option ;
|
||||||
|
}
|
||||||
|
|
||||||
val rights_for_level:
|
(** Compute the baking rights. By default, it computes the baking
|
||||||
'a #RPC_context.simple -> ?max_priority:int -> 'a -> Raw_level.t ->
|
rights for the next block and only returns the first available
|
||||||
(Raw_level.t * Signature.Public_key_hash.t list) shell_tzresult Lwt.t
|
priority for bakers that appears in the 64 first priorities.
|
||||||
|
|
||||||
val rights_for_delegate:
|
The optional arguments [levels] and [cycles] allows to compute
|
||||||
|
baking for an explicit list of levels or for all the levels of the given
|
||||||
|
cycles.
|
||||||
|
|
||||||
|
The optional argument [delegates] allows to filter
|
||||||
|
the non-explicitly listed delegates out of the resulting list.
|
||||||
|
|
||||||
|
When [all=false], the function only returns the minimal priority
|
||||||
|
for each delegates. When [all=true], all priorities are returned. *)
|
||||||
|
val get:
|
||||||
'a #RPC_context.simple ->
|
'a #RPC_context.simple ->
|
||||||
?max_priority:int -> ?first_level:Raw_level.t -> ?last_level:Raw_level.t ->
|
?levels: Raw_level.t list ->
|
||||||
'a -> Signature.Public_key_hash.t ->
|
?cycles: Cycle.t list ->
|
||||||
(Raw_level.t * int * Time.t) list shell_tzresult Lwt.t
|
?delegates: Signature.public_key_hash list ->
|
||||||
|
?all: bool ->
|
||||||
|
?max_priority: int ->
|
||||||
|
'a -> t list shell_tzresult Lwt.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Endorser : sig
|
module Endorsing_rights : sig
|
||||||
|
|
||||||
val rights:
|
type t = {
|
||||||
'a #RPC_context.simple -> ?max_priority:int -> 'a ->
|
level: Raw_level.t ;
|
||||||
(Raw_level.t * Signature.Public_key_hash.t list) shell_tzresult Lwt.t
|
delegate: Signature.Public_key_hash.t ;
|
||||||
|
slots: int list ;
|
||||||
|
estimated_time: Timestamp.t option ;
|
||||||
|
}
|
||||||
|
|
||||||
val rights_for_level:
|
(** Compute the endorsing rights. By default, it computes the
|
||||||
'a #RPC_context.simple -> ?max_priority:int -> 'a -> Raw_level.t ->
|
endorsing rights for the next block.
|
||||||
(Raw_level.t * Signature.Public_key_hash.t list) shell_tzresult Lwt.t
|
|
||||||
|
|
||||||
val rights_for_delegate:
|
The optional arguments [levels] and [cycles] allows to compute
|
||||||
|
baking for an explicit list of levels or for all the levels of
|
||||||
|
the given cycles.
|
||||||
|
|
||||||
|
The optional argument [delegates] allows to filter the
|
||||||
|
non-explicitly listed delegates out of the resulting list.. *)
|
||||||
|
val get:
|
||||||
'a #RPC_context.simple ->
|
'a #RPC_context.simple ->
|
||||||
?max_priority:int -> ?first_level:Raw_level.t -> ?last_level:Raw_level.t ->
|
?levels: Raw_level.t list ->
|
||||||
'a -> Signature.Public_key_hash.t ->
|
?cycles: Cycle.t list ->
|
||||||
(Raw_level.t * int) list shell_tzresult Lwt.t
|
?delegates: Signature.public_key_hash list ->
|
||||||
|
'a -> t list shell_tzresult Lwt.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
(* temporary export *)
|
(* temporary export for deprecated unit test *)
|
||||||
val endorsement_rights:
|
val endorsement_rights:
|
||||||
Alpha_context.t ->
|
Alpha_context.t ->
|
||||||
Level.t ->
|
Level.t ->
|
||||||
int option -> (Raw_level.t * public_key_hash list) tzresult Lwt.t
|
public_key_hash list tzresult Lwt.t
|
||||||
|
|
||||||
val baking_rights:
|
val baking_rights:
|
||||||
Alpha_context.t ->
|
Alpha_context.t ->
|
||||||
unit ->
|
|
||||||
int option ->
|
int option ->
|
||||||
(Raw_level.t * (public_key_hash * Time.t) list) tzresult Lwt.t
|
(Raw_level.t * (public_key_hash * Time.t option) list) tzresult Lwt.t
|
||||||
|
@ -30,14 +30,8 @@ let get_first_different_bakers ctxt =
|
|||||||
|
|
||||||
let get_first_different_endorsers ctxt =
|
let get_first_different_endorsers ctxt =
|
||||||
Context.get_endorsers ctxt >>=? fun endorsers ->
|
Context.get_endorsers ctxt >>=? fun endorsers ->
|
||||||
let endorsers = List.combine endorsers (0--((List.length endorsers) - 1)) in
|
let endorser_1 = (List.hd endorsers).delegate in
|
||||||
let endorser_1 = List.hd endorsers in
|
let endorser_2 = (List.hd (List.tl endorsers)).delegate in
|
||||||
let endorser_2 =
|
|
||||||
List.find (fun (endorser, _slot) ->
|
|
||||||
Signature.Public_key_hash.(<>)
|
|
||||||
(fst endorser_1) endorser)
|
|
||||||
(List.tl endorsers)
|
|
||||||
in
|
|
||||||
return (endorser_1, endorser_2)
|
return (endorser_1, endorser_2)
|
||||||
|
|
||||||
(** Bake two block at the same level using the same policy (i.e. same
|
(** Bake two block at the same level using the same policy (i.e. same
|
||||||
|
@ -30,14 +30,8 @@ let get_first_different_bakers ctxt =
|
|||||||
|
|
||||||
let get_first_different_endorsers ctxt =
|
let get_first_different_endorsers ctxt =
|
||||||
Context.get_endorsers ctxt >>=? fun endorsers ->
|
Context.get_endorsers ctxt >>=? fun endorsers ->
|
||||||
let endorsers = List.combine endorsers (0--((List.length endorsers) - 1)) in
|
let endorser_1 = (List.hd endorsers) in
|
||||||
let endorser_1 = List.hd endorsers in
|
let endorser_2 = (List.hd (List.tl endorsers)) in
|
||||||
let endorser_2 =
|
|
||||||
List.find (fun (endorser, _slot) ->
|
|
||||||
Signature.Public_key_hash.(<>)
|
|
||||||
(fst endorser_1) endorser)
|
|
||||||
(List.tl endorsers)
|
|
||||||
in
|
|
||||||
return (endorser_1, endorser_2)
|
return (endorser_1, endorser_2)
|
||||||
|
|
||||||
let block_fork b =
|
let block_fork b =
|
||||||
@ -59,8 +53,8 @@ let valid_double_endorsement_evidence () =
|
|||||||
block_fork b >>=? fun (blk_a, blk_b) ->
|
block_fork b >>=? fun (blk_a, blk_b) ->
|
||||||
|
|
||||||
Context.get_endorser (B blk_a) 0 >>=? fun delegate ->
|
Context.get_endorser (B blk_a) 0 >>=? fun delegate ->
|
||||||
Op.endorsement ~delegate (B blk_a) 0 >>=? fun endorsement_a ->
|
Op.endorsement ~delegate (B blk_a) [0] >>=? fun endorsement_a ->
|
||||||
Op.endorsement ~delegate (B blk_b) 0 >>=? fun endorsement_b ->
|
Op.endorsement ~delegate (B blk_b) [0] >>=? fun endorsement_b ->
|
||||||
Block.bake ~operations:[endorsement_a] blk_a >>=? fun blk_a ->
|
Block.bake ~operations:[endorsement_a] blk_a >>=? fun blk_a ->
|
||||||
(* Block.bake ~operations:[endorsement_b] blk_b >>=? fun _ -> *)
|
(* Block.bake ~operations:[endorsement_b] blk_b >>=? fun _ -> *)
|
||||||
|
|
||||||
@ -89,7 +83,7 @@ let invalid_double_endorsement () =
|
|||||||
Context.init 10 >>=? fun (b, _) ->
|
Context.init 10 >>=? fun (b, _) ->
|
||||||
Block.bake b >>=? fun b ->
|
Block.bake b >>=? fun b ->
|
||||||
|
|
||||||
Op.endorsement (B b) 0 >>=? fun endorsement ->
|
Op.endorsement (B b) [0] >>=? fun endorsement ->
|
||||||
Block.bake ~operation:endorsement b >>=? fun b ->
|
Block.bake ~operation:endorsement b >>=? fun b ->
|
||||||
|
|
||||||
Op.double_endorsement (B b) endorsement endorsement >>=? fun operation ->
|
Op.double_endorsement (B b) endorsement endorsement >>=? fun operation ->
|
||||||
@ -105,8 +99,8 @@ let too_early_double_endorsement_evidence () =
|
|||||||
block_fork b >>=? fun (blk_a, blk_b) ->
|
block_fork b >>=? fun (blk_a, blk_b) ->
|
||||||
|
|
||||||
Context.get_endorser (B blk_a) 0 >>=? fun delegate ->
|
Context.get_endorser (B blk_a) 0 >>=? fun delegate ->
|
||||||
Op.endorsement ~delegate (B blk_a) 0 >>=? fun endorsement_a ->
|
Op.endorsement ~delegate (B blk_a) [0] >>=? fun endorsement_a ->
|
||||||
Op.endorsement ~delegate (B blk_b) 0 >>=? fun endorsement_b ->
|
Op.endorsement ~delegate (B blk_b) [0] >>=? fun endorsement_b ->
|
||||||
|
|
||||||
Op.double_endorsement (B b) endorsement_a endorsement_b >>=? fun operation ->
|
Op.double_endorsement (B b) endorsement_a endorsement_b >>=? fun operation ->
|
||||||
Block.bake ~operation b >>= fun res ->
|
Block.bake ~operation b >>= fun res ->
|
||||||
@ -124,8 +118,8 @@ let too_late_double_endorsement_evidence () =
|
|||||||
block_fork b >>=? fun (blk_a, blk_b) ->
|
block_fork b >>=? fun (blk_a, blk_b) ->
|
||||||
|
|
||||||
Context.get_endorser (B blk_a) 0 >>=? fun delegate ->
|
Context.get_endorser (B blk_a) 0 >>=? fun delegate ->
|
||||||
Op.endorsement ~delegate (B blk_a) 0 >>=? fun endorsement_a ->
|
Op.endorsement ~delegate (B blk_a) [0] >>=? fun endorsement_a ->
|
||||||
Op.endorsement ~delegate (B blk_b) 0 >>=? fun endorsement_b ->
|
Op.endorsement ~delegate (B blk_b) [0] >>=? fun endorsement_b ->
|
||||||
|
|
||||||
fold_left_s (fun blk _ -> Block.bake_until_cycle_end blk)
|
fold_left_s (fun blk _ -> Block.bake_until_cycle_end blk)
|
||||||
blk_a (1 -- (preserved_cycles + 1)) >>=? fun blk ->
|
blk_a (1 -- (preserved_cycles + 1)) >>=? fun blk ->
|
||||||
@ -143,10 +137,10 @@ let different_delegates () =
|
|||||||
|
|
||||||
block_fork b >>=? fun (blk_a, blk_b) ->
|
block_fork b >>=? fun (blk_a, blk_b) ->
|
||||||
get_first_different_endorsers (B blk_a)
|
get_first_different_endorsers (B blk_a)
|
||||||
>>=? fun ((endorser_a, slot_a), (endorser_b, slot_b)) ->
|
>>=? fun (endorser_a, endorser_b) ->
|
||||||
|
|
||||||
Op.endorsement ~delegate:endorser_a (B blk_a) slot_a >>=? fun e_a ->
|
Op.endorsement ~delegate:endorser_a.delegate (B blk_a) endorser_a.slots >>=? fun e_a ->
|
||||||
Op.endorsement ~delegate:endorser_b (B blk_b) slot_b >>=? fun e_b ->
|
Op.endorsement ~delegate:endorser_b.delegate (B blk_b) endorser_b.slots >>=? fun e_b ->
|
||||||
Op.double_endorsement (B blk_a) e_a e_b >>=? fun operation ->
|
Op.double_endorsement (B blk_a) e_a e_b >>=? fun operation ->
|
||||||
Block.bake ~operation blk_a >>= fun res ->
|
Block.bake ~operation blk_a >>= fun res ->
|
||||||
Assert.proto_error ~loc:__LOC__ res begin function
|
Assert.proto_error ~loc:__LOC__ res begin function
|
||||||
@ -160,10 +154,10 @@ let wrong_delegate () =
|
|||||||
|
|
||||||
block_fork b >>=? fun (blk_a, blk_b) ->
|
block_fork b >>=? fun (blk_a, blk_b) ->
|
||||||
get_first_different_endorsers (B blk_a)
|
get_first_different_endorsers (B blk_a)
|
||||||
>>=? fun ((_endorser_a, slot_a), (endorser_b, slot_b)) ->
|
>>=? fun (endorser_a, endorser_b) ->
|
||||||
|
|
||||||
Op.endorsement ~delegate:endorser_b (B blk_a) slot_a >>=? fun endorsement_a ->
|
Op.endorsement ~delegate:endorser_b.delegate (B blk_a) endorser_a.slots >>=? fun endorsement_a ->
|
||||||
Op.endorsement ~delegate:endorser_b (B blk_b) slot_b >>=? fun endorsement_b ->
|
Op.endorsement ~delegate:endorser_b.delegate (B blk_b) endorser_b.slots >>=? fun endorsement_b ->
|
||||||
|
|
||||||
Op.double_endorsement (B blk_a) endorsement_a endorsement_b >>=? fun operation ->
|
Op.double_endorsement (B blk_a) endorsement_a endorsement_b >>=? fun operation ->
|
||||||
Block.bake ~operation blk_a >>= fun e ->
|
Block.bake ~operation blk_a >>= fun e ->
|
||||||
|
@ -61,16 +61,17 @@ let assert_endorser_balance_consistency ~loc ?(priority=0) ?(nb_baking=0) ~nb_en
|
|||||||
(** Apply a single endorsement from the slot 0 endorser *)
|
(** Apply a single endorsement from the slot 0 endorser *)
|
||||||
let simple_endorsement () =
|
let simple_endorsement () =
|
||||||
Context.init 5 >>=? fun (b, _) ->
|
Context.init 5 >>=? fun (b, _) ->
|
||||||
let slot = 0 in
|
let slot = 1 in
|
||||||
Incremental.begin_construction b >>=? fun inc ->
|
|
||||||
|
|
||||||
Context.get_endorser (B b) slot >>=? fun endorser ->
|
Context.get_endorser (B b) slot >>=? fun endorser ->
|
||||||
Op.endorsement ~delegate:endorser (I inc) slot >>=? fun op ->
|
Op.endorsement ~delegate:endorser (B b) [slot] >>=? fun op ->
|
||||||
Incremental.add_operation inc op >>=? fun inc ->
|
Context.Contract.balance (B b)
|
||||||
|
(Contract.implicit_contract endorser) >>=? fun initial_balance ->
|
||||||
Context.Contract.balance (B b) (Contract.implicit_contract endorser) >>=? fun initial_balance ->
|
Block.bake
|
||||||
|
~policy:(Excluding [endorser])
|
||||||
|
~operations:[op]
|
||||||
|
b >>=? fun b2 ->
|
||||||
assert_endorser_balance_consistency ~loc:__LOC__
|
assert_endorser_balance_consistency ~loc:__LOC__
|
||||||
(I inc) ~nb_endorsement:1 endorser initial_balance
|
(B b2) ~nb_endorsement:1 endorser initial_balance
|
||||||
|
|
||||||
(** Apply a maximum number of endorsement. A endorser can be selected
|
(** Apply a maximum number of endorsement. A endorser can be selected
|
||||||
twice. *)
|
twice. *)
|
||||||
@ -80,29 +81,25 @@ let max_endorsement () =
|
|||||||
|
|
||||||
Context.get_endorsers (B b) >>=? fun endorsers ->
|
Context.get_endorsers (B b) >>=? fun endorsers ->
|
||||||
Assert.equal_int ~loc:__LOC__
|
Assert.equal_int ~loc:__LOC__
|
||||||
(List.length endorsers) endorsers_per_block >>=? fun () ->
|
(List.length (List.concat (List.map (fun { Alpha_services.Delegate.Endorsing_rights.slots } -> slots) endorsers))) endorsers_per_block >>=? fun () ->
|
||||||
|
|
||||||
fold_left_s (fun (ops, balances) (delegate, slot) ->
|
fold_left_s (fun (delegates, ops, balances) (endorser : Alpha_services.Delegate.Endorsing_rights.t) ->
|
||||||
|
let delegate = endorser.delegate in
|
||||||
Context.Contract.balance (B b) (Contract.implicit_contract delegate) >>=? fun balance ->
|
Context.Contract.balance (B b) (Contract.implicit_contract delegate) >>=? fun balance ->
|
||||||
Op.endorsement ~delegate (B b) slot >>=? fun op ->
|
Op.endorsement ~delegate (B b) endorser.slots >>=? fun op ->
|
||||||
return (op :: ops, balance :: balances)
|
return (delegate :: delegates, op :: ops, (List.length endorser.slots, balance) :: balances)
|
||||||
)
|
)
|
||||||
([], [])
|
([], [], [])
|
||||||
(List.combine endorsers (0--(endorsers_per_block - 1))) >>=? fun (ops, previous_balances) ->
|
endorsers >>=? fun (delegates, ops, previous_balances) ->
|
||||||
|
|
||||||
Block.bake ~policy:(Excluding endorsers) ~operations:(List.rev ops) b >>=? fun b ->
|
Block.bake ~policy:(Excluding delegates) ~operations:(List.rev ops) b >>=? fun b ->
|
||||||
|
|
||||||
let count acc =
|
|
||||||
List.find_all ((=) acc) endorsers |> List.length
|
|
||||||
in
|
|
||||||
|
|
||||||
(* One account can endorse more than one time per level, we must
|
(* One account can endorse more than one time per level, we must
|
||||||
check that the bonds are summed up *)
|
check that the bonds are summed up *)
|
||||||
iter_s (fun (endorser_account, previous_balance) ->
|
iter_s (fun (endorser_account, (nb_endorsement, previous_balance)) ->
|
||||||
let nb_endorsement = count endorser_account in
|
|
||||||
assert_endorser_balance_consistency ~loc:__LOC__
|
assert_endorser_balance_consistency ~loc:__LOC__
|
||||||
(B b) ~nb_endorsement endorser_account previous_balance
|
(B b) ~nb_endorsement endorser_account previous_balance
|
||||||
) (List.combine endorsers (List.rev previous_balances))
|
) (List.combine delegates previous_balances)
|
||||||
|
|
||||||
(** Check that an endorser balance is consistent with a different piority *)
|
(** Check that an endorser balance is consistent with a different piority *)
|
||||||
let consistent_priority () =
|
let consistent_priority () =
|
||||||
@ -118,7 +115,7 @@ let consistent_priority () =
|
|||||||
in
|
in
|
||||||
Context.Contract.balance (B b) (Contract.implicit_contract endorser) >>=? fun balance ->
|
Context.Contract.balance (B b) (Contract.implicit_contract endorser) >>=? fun balance ->
|
||||||
|
|
||||||
Op.endorsement ~delegate:endorser (B b) slot >>=? fun operation ->
|
Op.endorsement ~delegate:endorser (B b) [slot] >>=? fun operation ->
|
||||||
Block.bake ~policy:( Excluding [ endorser ] ) ~operation b >>=? fun b ->
|
Block.bake ~policy:( Excluding [ endorser ] ) ~operation b >>=? fun b ->
|
||||||
|
|
||||||
assert_endorser_balance_consistency ~loc:__LOC__ ~priority:15
|
assert_endorser_balance_consistency ~loc:__LOC__ ~priority:15
|
||||||
@ -142,7 +139,7 @@ let consistent_priorities () =
|
|||||||
in
|
in
|
||||||
|
|
||||||
Context.Contract.balance (B b) (Contract.implicit_contract endorser) >>=? fun balance ->
|
Context.Contract.balance (B b) (Contract.implicit_contract endorser) >>=? fun balance ->
|
||||||
Op.endorsement ~delegate:endorser (B b) slot >>=? fun operation ->
|
Op.endorsement ~delegate:endorser (B b) [slot] >>=? fun operation ->
|
||||||
Block.bake ~policy:( Excluding [ endorser ] ) ~operation b >>=? fun b ->
|
Block.bake ~policy:( Excluding [ endorser ] ) ~operation b >>=? fun b ->
|
||||||
|
|
||||||
assert_endorser_balance_consistency ~loc:__LOC__ ~priority
|
assert_endorser_balance_consistency ~loc:__LOC__ ~priority
|
||||||
@ -158,7 +155,7 @@ let reward_retrieval () =
|
|||||||
let slot = 0 in
|
let slot = 0 in
|
||||||
Context.get_endorser (B b) slot >>=? fun endorser ->
|
Context.get_endorser (B b) slot >>=? fun endorser ->
|
||||||
Context.Contract.balance (B b) (Contract.implicit_contract endorser) >>=? fun balance ->
|
Context.Contract.balance (B b) (Contract.implicit_contract endorser) >>=? fun balance ->
|
||||||
Op.endorsement ~delegate:endorser (B b) slot >>=? fun operation ->
|
Op.endorsement ~delegate:endorser (B b) [slot] >>=? fun operation ->
|
||||||
Block.bake ~policy:(Excluding [ endorser ]) ~operation b >>=? fun b ->
|
Block.bake ~policy:(Excluding [ endorser ]) ~operation b >>=? fun b ->
|
||||||
(* Bake (preserved_cycles + 1) cycles *)
|
(* Bake (preserved_cycles + 1) cycles *)
|
||||||
fold_left_s (fun b _ ->
|
fold_left_s (fun b _ ->
|
||||||
@ -178,7 +175,7 @@ let wrong_endorsement_predecessor () =
|
|||||||
|
|
||||||
Context.get_endorser (B b) 0 >>=? fun genesis_endorser ->
|
Context.get_endorser (B b) 0 >>=? fun genesis_endorser ->
|
||||||
Block.bake b >>=? fun b' ->
|
Block.bake b >>=? fun b' ->
|
||||||
Op.endorsement ~delegate:genesis_endorser ~signing_context:(B b') (B b) 0 >>=? fun operation ->
|
Op.endorsement ~delegate:genesis_endorser ~signing_context:(B b') (B b) [0] >>=? fun operation ->
|
||||||
Block.bake ~operation b' >>= fun res ->
|
Block.bake ~operation b' >>= fun res ->
|
||||||
|
|
||||||
Assert.proto_error ~loc:__LOC__ res begin function
|
Assert.proto_error ~loc:__LOC__ res begin function
|
||||||
@ -192,7 +189,7 @@ let invalid_endorsement_level () =
|
|||||||
Context.init 5 >>=? fun (b, _) ->
|
Context.init 5 >>=? fun (b, _) ->
|
||||||
Context.get_level (B b) >>=? fun genesis_level ->
|
Context.get_level (B b) >>=? fun genesis_level ->
|
||||||
Block.bake b >>=? fun b ->
|
Block.bake b >>=? fun b ->
|
||||||
Op.endorsement ~level:genesis_level (B b) 0 >>=? fun operation ->
|
Op.endorsement ~level:genesis_level (B b) [0] >>=? fun operation ->
|
||||||
Block.bake ~operation b >>= fun res ->
|
Block.bake ~operation b >>= fun res ->
|
||||||
|
|
||||||
Assert.proto_error ~loc:__LOC__ res begin function
|
Assert.proto_error ~loc:__LOC__ res begin function
|
||||||
@ -204,9 +201,9 @@ let invalid_endorsement_level () =
|
|||||||
let duplicate_endorsement () =
|
let duplicate_endorsement () =
|
||||||
Context.init 5 >>=? fun (b, _) ->
|
Context.init 5 >>=? fun (b, _) ->
|
||||||
Incremental.begin_construction b >>=? fun inc ->
|
Incremental.begin_construction b >>=? fun inc ->
|
||||||
Op.endorsement (B b) 0 >>=? fun operation ->
|
Op.endorsement (B b) [0] >>=? fun operation ->
|
||||||
Incremental.add_operation inc operation >>=? fun inc ->
|
Incremental.add_operation inc operation >>=? fun inc ->
|
||||||
Op.endorsement (B b) 0 >>=? fun operation ->
|
Op.endorsement (B b) [0] >>=? fun operation ->
|
||||||
Incremental.add_operation inc operation >>= fun res ->
|
Incremental.add_operation inc operation >>= fun res ->
|
||||||
|
|
||||||
Assert.proto_error ~loc:__LOC__ res begin function
|
Assert.proto_error ~loc:__LOC__ res begin function
|
||||||
@ -219,8 +216,8 @@ let invalid_endorsement_slot () =
|
|||||||
Context.init 64 >>=? fun (b, _) ->
|
Context.init 64 >>=? fun (b, _) ->
|
||||||
Context.get_constants (B b) >>=? fun Constants.
|
Context.get_constants (B b) >>=? fun Constants.
|
||||||
{ parametric = { endorsers_per_block ; _ } ; _ } ->
|
{ parametric = { endorsers_per_block ; _ } ; _ } ->
|
||||||
|
Context.get_endorser (B b) 0 >>=? fun endorser ->
|
||||||
Op.endorsement (B b) (endorsers_per_block + 1) >>=? fun operation ->
|
Op.endorsement ~delegate:endorser (B b) [endorsers_per_block + 1] >>=? fun operation ->
|
||||||
|
|
||||||
Block.bake ~operation b >>= fun res ->
|
Block.bake ~operation b >>= fun res ->
|
||||||
|
|
||||||
|
@ -43,26 +43,31 @@ type baker_policy =
|
|||||||
| Excluding of public_key_hash list
|
| Excluding of public_key_hash list
|
||||||
|
|
||||||
let get_next_baker_by_priority priority block =
|
let get_next_baker_by_priority priority block =
|
||||||
Alpha_services.Delegate.Baker.rights rpc_ctxt
|
Alpha_services.Delegate.Baking_rights.get rpc_ctxt
|
||||||
~max_priority:(priority+1) block >>=? fun (_, bakers) ->
|
~all:true
|
||||||
let pkh, timestamp = List.nth bakers priority in
|
~max_priority:(priority+1) block >>=? fun bakers ->
|
||||||
return (pkh, priority, timestamp)
|
let { Alpha_services.Delegate.Baking_rights.delegate = pkh ;
|
||||||
|
timestamp} = List.find (fun { Alpha_services.Delegate.Baking_rights.priority = p } -> p = priority) bakers in
|
||||||
|
return (pkh, priority, Option.unopt_exn (Failure "") timestamp)
|
||||||
|
|
||||||
let get_next_baker_by_account pkh block =
|
let get_next_baker_by_account pkh block =
|
||||||
Alpha_services.Delegate.Baker.rights rpc_ctxt
|
Alpha_services.Delegate.Baking_rights.get rpc_ctxt
|
||||||
~max_priority:30 block >>=? fun (_, bakers) ->
|
~delegates:[pkh]
|
||||||
let ((_pkh, timestamp), priority) = Test_utils.findi
|
~max_priority:256 block >>=? fun bakers ->
|
||||||
(fun (pkh', _) -> Signature.Public_key_hash.equal pkh pkh')
|
let { Alpha_services.Delegate.Baking_rights.delegate = pkh ;
|
||||||
bakers in
|
timestamp ; priority } = List.hd bakers in
|
||||||
return (pkh, priority, timestamp)
|
return (pkh, priority, Option.unopt_exn (Failure "") timestamp)
|
||||||
|
|
||||||
let get_next_baker_excluding excludes block =
|
let get_next_baker_excluding excludes block =
|
||||||
Alpha_services.Delegate.Baker.rights rpc_ctxt
|
Alpha_services.Delegate.Baking_rights.get rpc_ctxt
|
||||||
~max_priority:((List.length excludes)+10) block >>=? fun (_, bakers) ->
|
~max_priority:256 block >>=? fun bakers ->
|
||||||
let (pkh,timestamp),priority = Test_utils.findi
|
let { Alpha_services.Delegate.Baking_rights.delegate = pkh ;
|
||||||
(fun (pkh, _) -> not (List.mem pkh excludes))
|
timestamp ; priority } =
|
||||||
|
List.find
|
||||||
|
(fun { Alpha_services.Delegate.Baking_rights.delegate } ->
|
||||||
|
not (List.mem delegate excludes))
|
||||||
bakers in
|
bakers in
|
||||||
return (pkh, priority, timestamp)
|
return (pkh, priority, Option.unopt_exn (Failure "") timestamp)
|
||||||
|
|
||||||
let dispatch_policy = function
|
let dispatch_policy = function
|
||||||
| By_priority p -> get_next_baker_by_priority p
|
| By_priority p -> get_next_baker_by_priority p
|
||||||
@ -112,9 +117,14 @@ module Forge = struct
|
|||||||
(* Finds the baker that should sign from the header *)
|
(* Finds the baker that should sign from the header *)
|
||||||
let baker_of_a_block header =
|
let baker_of_a_block header =
|
||||||
let priority = header.contents.priority in
|
let priority = header.contents.priority in
|
||||||
Alpha_services.Delegate.Baker.rights rpc_ctxt
|
Alpha_services.Delegate.Baking_rights.get rpc_ctxt
|
||||||
~max_priority:(priority+1) pred >>=? fun (_, bakers) ->
|
~all:true
|
||||||
let pkh, _ = List.nth bakers priority in
|
~max_priority:(priority+1)
|
||||||
|
pred >>=? fun bakers ->
|
||||||
|
let { Alpha_services.Delegate.Baking_rights.delegate = pkh } =
|
||||||
|
List.find
|
||||||
|
(fun { Alpha_services.Delegate.Baking_rights.priority = p } -> p = priority)
|
||||||
|
bakers in
|
||||||
Account.find pkh
|
Account.find pkh
|
||||||
in
|
in
|
||||||
baker_of_a_block { shell ; contents } >>=? fun delegate ->
|
baker_of_a_block { shell ; contents } >>=? fun delegate ->
|
||||||
|
@ -64,21 +64,23 @@ let rpc_ctxt = object
|
|||||||
end
|
end
|
||||||
|
|
||||||
let get_endorsers ctxt =
|
let get_endorsers ctxt =
|
||||||
Alpha_services.Delegate.Endorser.rights
|
Alpha_services.Delegate.Endorsing_rights.get rpc_ctxt ctxt
|
||||||
rpc_ctxt ctxt >>=? fun (_level, endorsers) ->
|
|
||||||
return endorsers
|
|
||||||
|
|
||||||
let get_endorser ctxt slot =
|
let get_endorser ctxt slot =
|
||||||
Alpha_services.Delegate.Endorser.rights
|
Alpha_services.Delegate.Endorsing_rights.get
|
||||||
~max_priority:(slot+1) rpc_ctxt ctxt >>=? fun (_level, endorsers) ->
|
rpc_ctxt ctxt >>=? fun endorsers ->
|
||||||
try return (List.nth endorsers slot)
|
try return (List.find (fun {Alpha_services.Delegate.Endorsing_rights.slots} -> List.mem slot slots) endorsers).delegate
|
||||||
with _ ->
|
with _ ->
|
||||||
failwith "Failed to lookup endorsers for ctxt %a, slot %d."
|
failwith "Failed to lookup endorsers for ctxt %a, slot %d."
|
||||||
Block_hash.pp_short (branch ctxt) slot
|
Block_hash.pp_short (branch ctxt) slot
|
||||||
|
|
||||||
let get_bakers ctxt =
|
let get_bakers ctxt =
|
||||||
Alpha_services.Delegate.Baker.rights rpc_ctxt ~max_priority:30 ctxt >>=? fun (_, bakers) ->
|
Alpha_services.Delegate.Baking_rights.get
|
||||||
return (List.map fst bakers)
|
~max_priority:256
|
||||||
|
rpc_ctxt ctxt >>=? fun bakers ->
|
||||||
|
return (List.map
|
||||||
|
(fun p -> p.Alpha_services.Delegate.Baking_rights.delegate)
|
||||||
|
bakers)
|
||||||
|
|
||||||
let get_constants b =
|
let get_constants b =
|
||||||
Alpha_services.Constants.all rpc_ctxt b
|
Alpha_services.Constants.all rpc_ctxt b
|
||||||
|
@ -18,7 +18,7 @@ val branch: t -> Block_hash.t
|
|||||||
|
|
||||||
val get_level: t -> Raw_level.t tzresult Lwt.t
|
val get_level: t -> Raw_level.t tzresult Lwt.t
|
||||||
|
|
||||||
val get_endorsers: t -> public_key_hash list tzresult Lwt.t
|
val get_endorsers: t -> Alpha_services.Delegate.Endorsing_rights.t list tzresult Lwt.t
|
||||||
|
|
||||||
val get_endorser: t -> int -> public_key_hash tzresult Lwt.t
|
val get_endorser: t -> int -> public_key_hash tzresult Lwt.t
|
||||||
|
|
||||||
|
@ -25,10 +25,10 @@ let sign ?(watermark = Signature.Generic_operation) sk ctxt contents =
|
|||||||
}
|
}
|
||||||
|
|
||||||
let endorsement ?delegate ?level ctxt =
|
let endorsement ?delegate ?level ctxt =
|
||||||
fun ?(signing_context=ctxt) slot ->
|
fun ?(signing_context=ctxt) slots ->
|
||||||
begin
|
begin
|
||||||
match delegate with
|
match delegate with
|
||||||
| None -> Context.get_endorser ctxt slot
|
| None -> Context.get_endorser ctxt (List.hd slots)
|
||||||
| Some delegate -> return delegate
|
| Some delegate -> return delegate
|
||||||
end >>=? fun delegate_pkh ->
|
end >>=? fun delegate_pkh ->
|
||||||
Account.find delegate_pkh >>=? fun delegate ->
|
Account.find delegate_pkh >>=? fun delegate ->
|
||||||
@ -38,7 +38,7 @@ let endorsement ?delegate ?level ctxt =
|
|||||||
| Some level -> return level
|
| Some level -> return level
|
||||||
end >>=? fun level ->
|
end >>=? fun level ->
|
||||||
let op =
|
let op =
|
||||||
let operations = Endorsements { block = Context.branch ctxt ; level ; slots = [slot] } in
|
let operations = Endorsements { block = Context.branch ctxt ; level ; slots = slots } in
|
||||||
Sourced_operation (Consensus_operation operations) in
|
Sourced_operation (Consensus_operation operations) in
|
||||||
return (sign ~watermark:Signature.Endorsement delegate.sk signing_context op)
|
return (sign ~watermark:Signature.Endorsement delegate.sk signing_context op)
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ let miss_signed_endorsement ?level ctxt slot =
|
|||||||
end >>=? fun level ->
|
end >>=? fun level ->
|
||||||
Context.get_endorser ctxt slot >>=? fun real_delegate_pkh ->
|
Context.get_endorser ctxt slot >>=? fun real_delegate_pkh ->
|
||||||
let delegate = Account.find_alternate real_delegate_pkh in
|
let delegate = Account.find_alternate real_delegate_pkh in
|
||||||
endorsement ~delegate:delegate.pkh ~level ctxt slot
|
endorsement ~delegate:delegate.pkh ~level ctxt [slot]
|
||||||
|
|
||||||
let transaction ?fee ?gas_limit ?storage_limit ?parameters ctxt
|
let transaction ?fee ?gas_limit ?storage_limit ?parameters ctxt
|
||||||
(src:Contract.t) (dst:Contract.t)
|
(src:Contract.t) (dst:Contract.t)
|
||||||
|
@ -14,7 +14,7 @@ val endorsement:
|
|||||||
?delegate:public_key_hash ->
|
?delegate:public_key_hash ->
|
||||||
?level:Raw_level.t ->
|
?level:Raw_level.t ->
|
||||||
Context.t -> ?signing_context:Context.t ->
|
Context.t -> ?signing_context:Context.t ->
|
||||||
int -> Operation.t tzresult Lwt.t
|
int list -> Operation.t tzresult Lwt.t
|
||||||
|
|
||||||
val miss_signed_endorsement:
|
val miss_signed_endorsement:
|
||||||
?level:Raw_level.t ->
|
?level:Raw_level.t ->
|
||||||
|
Loading…
Reference in New Issue
Block a user