diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_voting.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_voting.ml index b2d47834a34f656c06f8bb0f5fc3f4484e5517fd..a419b599eacea76ddcc5b709a0bfcc7a1003e2c8 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/test_voting.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_voting.ml @@ -185,7 +185,8 @@ let assert_period ?expected_kind ?expected_kinds ?expected_index | None -> return_unit let assert_ballots expected_ballots b loc = - Context.Vote.get_ballots (B b) >>=? fun ballots -> + let open Lwt_result_syntax in + let* ballots = Context.Vote.get_ballots (B b) in Assert.equal ~loc Vote.equal_ballots @@ -195,8 +196,10 @@ let assert_ballots expected_ballots b loc = expected_ballots let assert_empty_ballots b loc = - assert_ballots Vote.ballots_zero b loc >>=? fun () -> - Context.Vote.get_ballot_list (B b) >>=? function + let open Lwt_result_syntax in + let* () = assert_ballots Vote.ballots_zero b loc in + let* l = Context.Vote.get_ballot_list (B b) in + match l with | [] -> return_unit | _ -> failwith "%s - Unexpected ballot list" loc @@ -205,15 +208,17 @@ let mk_contracts_from_pkh pkh_list = (* get the list of delegates and the list of their voting power from listings *) let get_delegates_and_power_from_listings b = - Context.Vote.get_listings (B b) >|=? fun l -> + let open Lwt_result_syntax in + let+ l = Context.Vote.get_listings (B b) in (mk_contracts_from_pkh (List.map fst l), List.map snd l) (* compute the voting power of each delegate *) let get_power b delegates loc = + let open Lwt_result_syntax in List.map_es (fun delegate -> let pkh = Context.Contract.pkh delegate in - Context.Delegate.voting_info (B b) pkh >>=? fun info -> + let* info = Context.Delegate.voting_info (B b) pkh in match info.voting_power with | None -> failwith "%s - Missing delegate" loc | Some power -> return power) @@ -221,7 +226,9 @@ let get_power b delegates loc = (* Checks that the listings are populated *) let assert_listings_not_empty b ~loc = - Context.Vote.get_listings (B b) >>=? function + let open Lwt_result_syntax in + let* l = Context.Vote.get_listings (B b) in + match l with | [] -> failwith "Unexpected empty listings (%s)" loc | _ -> return_unit @@ -244,7 +251,8 @@ let assert_equal_info ~loc a b = b let bake_until_first_block_of_next_period ?policy b = - Context.Vote.get_current_period (B b) >>=? fun {remaining; _} -> + let open Lwt_result_syntax in + let* {remaining; _} = Context.Vote.get_current_period (B b) in Block.bake_n ?policy Int32.(add remaining one |> to_int) b let context_init_tup tup ?(blocks_per_cycle = 4l) = @@ -430,39 +438,47 @@ let assert_validate_ballot_fails ~expected_error ~voter ~proposal ~ballot (** A normal and successful vote sequence. *) let test_successful_vote num_delegates () = + let open Lwt_result_syntax in let open Alpha_context in let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - context_init ~min_proposal_quorum num_delegates () >>=? fun (b, _) -> + let* b, (_ : Contract.t list) = + context_init ~min_proposal_quorum num_delegates () + in (* no ballots in proposal period *) - assert_empty_ballots b __LOC__ >>=? fun () -> + let* () = assert_empty_ballots b __LOC__ in (* Last baked block is first block of period Proposal *) - assert_period - ~expected_kind:Proposal - ~expected_index:0l - ~expected_position:0l - b - __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* () = + assert_period + ~expected_kind:Proposal + ~expected_index:0l + ~expected_position:0l + b + __LOC__ + in + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* participation EMA starts at initial_participation *) - Context.Vote.get_participation_ema b >>=? fun v -> - Assert.equal_int ~loc:__LOC__ initial_participation (Int32.to_int v) - >>=? fun () -> + let* v = Context.Vote.get_participation_ema b in + let* () = + Assert.equal_int ~loc:__LOC__ initial_participation (Int32.to_int v) + in (* listings must be populated in proposal period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* beginning of proposal, denoted by _p1; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p1, power_p1) -> + let* delegates_p1, power_p1 = get_delegates_and_power_from_listings b in (* no proposals at the beginning of proposal period *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (if Environment.Protocol_hash.Map.is_empty ps then return_unit - else failwith "%s - Unexpected proposals" __LOC__) - >>=? fun () -> + let* ps = Context.Vote.get_proposals (B b) in + let* () = + if Environment.Protocol_hash.Map.is_empty ps then return_unit + else failwith "%s - Unexpected proposals" __LOC__ + in (* no current proposal during proposal period *) - (Context.Vote.get_current_proposal (B b) >>=? function - | None -> return_unit - | Some _ -> failwith "%s - Unexpected proposal" __LOC__) - >>=? fun () -> + let* () = + let* proposal = Context.Vote.get_current_proposal (B b) in + match proposal with + | None -> return_unit + | Some _ -> failwith "%s - Unexpected proposal" __LOC__ + in let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates_p1 0 in @@ -476,205 +492,233 @@ let test_successful_vote num_delegates () = let props = List.map (fun i -> protos.(i)) (2 -- Constants.max_proposals_per_delegate) in - Op.proposals (B b) del1 (Protocol_hash.zero :: props) >>=? fun ops1 -> - Op.proposals (B b) del2 [Protocol_hash.zero] >>=? fun ops2 -> - Block.bake ~operations:[ops1; ops2] b >>=? fun b -> - Context.Delegate.voting_info (B b) pkh1 >>=? fun info1 -> - Context.Delegate.voting_info (B b) pkh2 >>=? fun info2 -> - assert_equal_info - ~loc:__LOC__ - info1 - { - voting_power = Some pow1; - current_ballot = None; - current_proposals = Protocol_hash.zero :: props; - remaining_proposals = 0; - } - >>=? fun () -> - assert_equal_info - ~loc:__LOC__ - info2 - { - voting_power = Some pow2; - current_ballot = None; - current_proposals = [Protocol_hash.zero]; - remaining_proposals = Constants.max_proposals_per_delegate - 1; - } - >>=? fun () -> + let* ops1 = Op.proposals (B b) del1 (Protocol_hash.zero :: props) in + let* ops2 = Op.proposals (B b) del2 [Protocol_hash.zero] in + let* b = Block.bake ~operations:[ops1; ops2] b in + let* info1 = Context.Delegate.voting_info (B b) pkh1 in + let* info2 = Context.Delegate.voting_info (B b) pkh2 in + let* () = + assert_equal_info + ~loc:__LOC__ + info1 + { + voting_power = Some pow1; + current_ballot = None; + current_proposals = Protocol_hash.zero :: props; + remaining_proposals = 0; + } + in + let* () = + assert_equal_info + ~loc:__LOC__ + info2 + { + voting_power = Some pow2; + current_ballot = None; + current_proposals = [Protocol_hash.zero]; + remaining_proposals = Constants.max_proposals_per_delegate - 1; + } + in (* proposals are now populated *) - Context.Vote.get_proposals (B b) >>=? fun ps -> + let* ps = Context.Vote.get_proposals (B b) in (* correctly count the double proposal for zero *) - (let weight = - Int64.add - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth power_p1 0) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth power_p1 1) - in - match Environment.Protocol_hash.(Map.find zero ps) with - | Some v -> - if v = weight then return_unit - else failwith "%s - Wrong count %Ld is not %Ld" __LOC__ v weight - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> + let* () = + let weight = + Int64.add + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth power_p1 0) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth power_p1 1) + in + match Environment.Protocol_hash.(Map.find zero ps) with + | Some v -> + if v = weight then return_unit + else failwith "%s - Wrong count %Ld is not %Ld" __LOC__ v weight + | None -> failwith "%s - Missing proposal" __LOC__ + in (* proposing more than maximum_proposals fails *) - assert_validate_proposals_fails - ~expected_error:too_many_proposals - ~proposer:del1 - ~proposals:(Protocol_hash.zero :: props) - b - __LOC__ - >>=? fun () -> + let* () = + assert_validate_proposals_fails + ~expected_error:too_many_proposals + ~proposer:del1 + ~proposals:(Protocol_hash.zero :: props) + b + __LOC__ + in (* proposing less than one proposal fails *) - assert_validate_proposals_fails - ~expected_error:empty_proposals - ~proposer:del1 - ~proposals:[] - b - __LOC__ - >>=? fun () -> + let* () = + assert_validate_proposals_fails + ~expected_error:empty_proposals + ~proposer:del1 + ~proposals:[] + b + __LOC__ + in (* first block of exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* next block is first block of exploration *) - assert_period ~expected_kind:Exploration ~expected_index:1l b __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* () = + assert_period ~expected_kind:Exploration ~expected_index:1l b __LOC__ + in + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* listings must be populated in proposal period before moving to exploration period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* beginning of exploration period, denoted by _p2; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p2, power_p2) -> + let* delegates_p2, power_p2 = get_delegates_and_power_from_listings b in (* no proposals during exploration period *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (if Environment.Protocol_hash.Map.is_empty ps then return_unit - else failwith "%s - Unexpected proposals" __LOC__) - >>=? fun () -> + let* ps = Context.Vote.get_proposals (B b) in + let* () = + if Environment.Protocol_hash.Map.is_empty ps then return_unit + else failwith "%s - Unexpected proposals" __LOC__ + in (* current proposal must be set during exploration period *) - (Context.Vote.get_current_proposal (B b) >>=? function - | Some v -> - if Protocol_hash.(equal zero v) then return_unit - else failwith "%s - Wrong proposal" __LOC__ - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> + let* () = + let* v_opt = Context.Vote.get_current_proposal (B b) in + match v_opt with + | Some v -> + if Protocol_hash.(equal zero v) then return_unit + else failwith "%s - Wrong proposal" __LOC__ + | None -> failwith "%s - Missing proposal" __LOC__ + in (* unanimous vote: all delegates --active when p2 started-- vote *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - delegates_p2 - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - Context.Delegate.voting_info (B b) pkh1 >>=? fun info1 -> - assert_equal_info - ~loc:__LOC__ - info1 - { - voting_power = Some pow1; - current_ballot = Some Yay; - current_proposals = []; - remaining_proposals = 0; - } - >>=? fun () -> + let* operations = + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + delegates_p2 + in + let* b = Block.bake ~operations b in + let* info1 = Context.Delegate.voting_info (B b) pkh1 in + let* () = + assert_equal_info + ~loc:__LOC__ + info1 + { + voting_power = Some pow1; + current_ballot = Some Yay; + current_proposals = []; + remaining_proposals = 0; + } + in (* Submitting a second ballot for [del1] fails (indeed, [del1] belongs to [delegates_p2], so they have already sent a ballot during the unanimous vote right above). *) - assert_validate_ballot_fails - ~expected_error:already_submitted_a_ballot - ~voter:del1 - ~proposal:Protocol_hash.zero - ~ballot:Vote.Nay - b - __LOC__ - >>=? fun () -> + let* () = + assert_validate_ballot_fails + ~expected_error:already_submitted_a_ballot + ~voter:del1 + ~proposal:Protocol_hash.zero + ~ballot:Vote.Nay + b + __LOC__ + in (* Allocate votes from weight of active delegates *) List.fold_left (fun acc v -> Int64.(add v acc)) 0L power_p2 |> fun power_sum -> (* # of Yay in ballots matches votes of the delegates *) - assert_ballots Vote.{yay = power_sum; nay = 0L; pass = 0L} b __LOC__ - >>=? fun () -> + let* () = + assert_ballots Vote.{yay = power_sum; nay = 0L; pass = 0L} b __LOC__ + in (* One Yay ballot per delegate *) - (Context.Vote.get_ballot_list (B b) >>=? function - | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ - | l -> - List.iter_es - (fun delegate -> - let pkh = Context.Contract.pkh delegate in - match List.find_opt (fun (del, _) -> del = pkh) l with - | None -> failwith "%s - Missing delegate" __LOC__ - | Some (_, Vote.Yay) -> return_unit - | Some _ -> failwith "%s - Wrong ballot" __LOC__) - delegates_p2) - >>=? fun () -> + let* () = + let* l_opt = Context.Vote.get_ballot_list (B b) in + match l_opt with + | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ + | l -> + List.iter_es + (fun delegate -> + let pkh = Context.Contract.pkh delegate in + match List.find_opt (fun (del, _) -> del = pkh) l with + | None -> failwith "%s - Missing delegate" __LOC__ + | Some (_, Vote.Yay) -> return_unit + | Some _ -> failwith "%s - Wrong ballot" __LOC__) + delegates_p2 + in (* skip to cooldown period *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_index:2l ~expected_kind:Cooldown b __LOC__ - >>=? fun () -> + let* b = bake_until_first_block_of_next_period b in + let* () = + assert_period ~expected_index:2l ~expected_kind:Cooldown b __LOC__ + in (* no ballots in cooldown period *) - assert_empty_ballots b __LOC__ >>=? fun () -> + let* () = assert_empty_ballots b __LOC__ in (* listings must be populated in cooldown period before moving to promotion_vote period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* skip to promotion period *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Promotion ~expected_index:3l b __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* b = bake_until_first_block_of_next_period b in + let* () = + assert_period ~expected_kind:Promotion ~expected_index:3l b __LOC__ + in + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* period 3 *) (* listings must be populated in promotion period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* beginning of promotion period, denoted by _p4; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p4, power_p4) -> + let* delegates_p4, power_p4 = get_delegates_and_power_from_listings b in (* no proposals during promotion period *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (if Environment.Protocol_hash.Map.is_empty ps then return_unit - else failwith "%s - Unexpected proposals" __LOC__) - >>=? fun () -> + let* ps = Context.Vote.get_proposals (B b) in + let* () = + if Environment.Protocol_hash.Map.is_empty ps then return_unit + else failwith "%s - Unexpected proposals" __LOC__ + in (* current proposal must be set during promotion period *) - (Context.Vote.get_current_proposal (B b) >>=? function - | Some v -> - if Protocol_hash.(equal zero v) then return_unit - else failwith "%s - Wrong proposal" __LOC__ - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> + let* () = + let* v_opt = Context.Vote.get_current_proposal (B b) in + match v_opt with + | Some v -> + if Protocol_hash.(equal zero v) then return_unit + else failwith "%s - Wrong proposal" __LOC__ + | None -> failwith "%s - Missing proposal" __LOC__ + in (* unanimous vote: all delegates --active when p4 started-- vote *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - delegates_p4 - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> + let* operations = + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + delegates_p4 + in + let* b = Block.bake ~operations b in List.fold_left (fun acc v -> Int64.(add v acc)) 0L power_p4 |> fun power_sum -> (* # of Yays in ballots matches voting power of the delegate *) - assert_ballots Vote.{yay = power_sum; nay = 0L; pass = 0L} b __LOC__ - >>=? fun () -> + let* () = + assert_ballots Vote.{yay = power_sum; nay = 0L; pass = 0L} b __LOC__ + in (* One Yay ballot per delegate *) - (Context.Vote.get_ballot_list (B b) >>=? function - | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ - | l -> - List.iter_es - (fun delegate -> - let pkh = Context.Contract.pkh delegate in - match List.find_opt (fun (del, _) -> del = pkh) l with - | None -> failwith "%s - Missing delegate" __LOC__ - | Some (_, Vote.Yay) -> return_unit - | Some _ -> failwith "%s - Wrong ballot" __LOC__) - delegates_p4) - >>=? fun () -> + let* () = + let* l_opt = Context.Vote.get_ballot_list (B b) in + match l_opt with + | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ + | l -> + List.iter_es + (fun delegate -> + let pkh = Context.Contract.pkh delegate in + match List.find_opt (fun (del, _) -> del = pkh) l with + | None -> failwith "%s - Missing delegate" __LOC__ + | Some (_, Vote.Yay) -> return_unit + | Some _ -> failwith "%s - Wrong ballot" __LOC__) + delegates_p4 + in (* skip to end of promotion period and activation*) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Adoption ~expected_index:4l b __LOC__ - >>=? fun () -> + let* b = bake_until_first_block_of_next_period b in + let* () = + assert_period ~expected_kind:Adoption ~expected_index:4l b __LOC__ + in (* skip to end of Adoption period and bake 1 more to activate *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Proposal ~expected_index:5l b __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + let* b = bake_until_first_block_of_next_period b in + let* () = + assert_period ~expected_kind:Proposal ~expected_index:5l b __LOC__ + in + let* () = assert_listings_not_empty b ~loc:__LOC__ in (* zero is the new protocol (before the vote this value is unset) *) - Context.Vote.get_protocol b >>= fun p -> - Assert.equal - ~loc:__LOC__ - Protocol_hash.equal - "Unexpected proposal" - Protocol_hash.pp - p - Protocol_hash.zero - >>=? fun () -> return_unit + let*! p = Context.Vote.get_protocol b in + let* () = + Assert.equal + ~loc:__LOC__ + Protocol_hash.equal + "Unexpected proposal" + Protocol_hash.pp + p + Protocol_hash.zero + in + return_unit (* given a list of active delegates, return the first k active delegates with which one can have quorum, that is: @@ -717,147 +761,159 @@ let get_expected_participation_ema power voter_power old_participation_ema = -- get_updated_participation_ema < pr_ema_weight/den -- in exploration, go back to proposal period. *) let test_not_enough_quorum_in_exploration num_delegates () = + let open Lwt_result_syntax in let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - context_init ~min_proposal_quorum num_delegates () >>=? fun (b, delegates) -> + let* b, delegates = context_init ~min_proposal_quorum num_delegates () in (* proposal period *) let open Alpha_context in - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Proposal b __LOC__ in let proposer = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in - Op.proposals (B b) proposer [Protocol_hash.zero] >>=? fun operation -> - Block.bake ~operation b >>=? fun b -> + let* operation = Op.proposals (B b) proposer [Protocol_hash.zero] in + let* b = Block.bake ~operation b in (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> - Context.Vote.get_participation_ema b >>=? fun initial_participation_ema -> + let* () = assert_period ~expected_kind:Exploration b __LOC__ in + let* initial_participation_ema = Context.Vote.get_participation_ema b in (* beginning of exploration period, denoted by _p2; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p2, power_p2) -> - Context.Vote.get_participation_ema b >>=? fun participation_ema -> + let* delegates_p2, power_p2 = get_delegates_and_power_from_listings b in + let* participation_ema = Context.Vote.get_participation_ema b in get_smallest_prefix_voters_for_quorum delegates_p2 power_p2 participation_ema |> fun voters -> (* take the first two voters out so there cannot be quorum *) let voters_without_quorum = WithExceptions.Option.get ~loc:__LOC__ @@ List.tl voters in - get_power b voters_without_quorum __LOC__ - >>=? fun voters_power_in_exploration -> + let* voters_power_in_exploration = + get_power b voters_without_quorum __LOC__ + in (* all voters_without_quorum vote, for yays; no nays, so supermajority is satisfied *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - voters_without_quorum - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> + let* operations = + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + voters_without_quorum + in + let* b = Block.bake ~operations b in (* bake to next period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* we move back to the proposal period because not enough quorum *) - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Proposal b __LOC__ in (* check participation_ema update *) get_expected_participation_ema power_p2 voters_power_in_exploration initial_participation_ema |> fun expected_participation_ema -> - Context.Vote.get_participation_ema b >>=? fun new_participation_ema -> + let* new_participation_ema = Context.Vote.get_participation_ema b in (* assert the formula to calculate participation_ema is correct *) - Assert.equal_int - ~loc:__LOC__ - expected_participation_ema - (Int32.to_int new_participation_ema) - >>=? fun () -> return_unit + let* () = + Assert.equal_int + ~loc:__LOC__ + expected_participation_ema + (Int32.to_int new_participation_ema) + in + return_unit (** If not enough quorum -- get_updated_participation_ema < pr_ema_weight/den -- In promotion period, go back to proposal period. *) let test_not_enough_quorum_in_promotion num_delegates () = + let open Lwt_result_syntax in let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - context_init ~min_proposal_quorum num_delegates () >>=? fun (b, delegates) -> - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let* b, delegates = context_init ~min_proposal_quorum num_delegates () in + let* () = assert_period ~expected_kind:Proposal b __LOC__ in let proposer = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in - Op.proposals (B b) proposer [Protocol_hash.zero] >>=? fun operation -> - Block.bake ~operation b >>=? fun b -> + let* operation = Op.proposals (B b) proposer [Protocol_hash.zero] in + let* b = Block.bake ~operation b in (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Exploration b __LOC__ in (* beginning of exploration period, denoted by _p2; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p2, power_p2) -> - Context.Vote.get_participation_ema b >>=? fun participation_ema -> + let* delegates_p2, power_p2 = get_delegates_and_power_from_listings b in + let* participation_ema = Context.Vote.get_participation_ema b in get_smallest_prefix_voters_for_quorum delegates_p2 power_p2 participation_ema |> fun voters -> let open Alpha_context in (* all voters vote, for yays; no nays, so supermajority is satisfied *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - voters - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> + let* operations = + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + voters + in + let* b = Block.bake ~operations b in (* skip to first block cooldown period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* we move to cooldown because we have supermajority and enough quorum *) - assert_period ~expected_kind:Cooldown b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Cooldown b __LOC__ in (* skip to first block of promotion period *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Promotion b __LOC__ - (* bake_until_first_block_of_next_period ~offset:1l b - * >>=? fun b -> - * assert_period ~expected_kind:Promotion b __LOC__ *) - >>=? - fun () -> - Context.Vote.get_participation_ema b >>=? fun initial_participation_ema -> + let* b = bake_until_first_block_of_next_period b in + let* () = + assert_period ~expected_kind:Promotion b __LOC__ + (* let* b = bake_until_first_block_of_next_period ~offset:1l b + * in assert_period ~expected_kind:Promotion b __LOC__ *) + in + let* initial_participation_ema = Context.Vote.get_participation_ema b in (* beginning of promotion period, denoted by _p4; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p4, power_p4) -> - Context.Vote.get_participation_ema b >>=? fun participation_ema -> + let* delegates_p4, power_p4 = get_delegates_and_power_from_listings b in + let* participation_ema = Context.Vote.get_participation_ema b in get_smallest_prefix_voters_for_quorum delegates_p4 power_p4 participation_ema |> fun voters -> (* take the first voter out so there cannot be quorum *) let voters_without_quorum = WithExceptions.Option.get ~loc:__LOC__ @@ List.tl voters in - get_power b voters_without_quorum __LOC__ >>=? fun voter_power -> + let* voter_power = get_power b voters_without_quorum __LOC__ in (* all voters_without_quorum vote, for yays; no nays, so supermajority is satisfied *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - voters_without_quorum - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> + let* operations = + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + voters_without_quorum + in + let* b = Block.bake ~operations b in (* skip to end of promotion period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in get_expected_participation_ema power_p4 voter_power initial_participation_ema |> fun expected_participation_ema -> - Context.Vote.get_participation_ema b >>=? fun new_participation_ema -> + let* new_participation_ema = Context.Vote.get_participation_ema b in (* assert the formula to calculate participation_ema is correct *) - Assert.equal_int - ~loc:__LOC__ - expected_participation_ema - (Int32.to_int new_participation_ema) - >>=? fun () -> + let* () = + Assert.equal_int + ~loc:__LOC__ + expected_participation_ema + (Int32.to_int new_participation_ema) + in (* we move back to the proposal period because not enough quorum *) - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> return_unit + let* () = assert_period ~expected_kind:Proposal b __LOC__ in + let* () = assert_listings_not_empty b ~loc:__LOC__ in + return_unit (** Assume the initial balance of accounts allocated by Context.init_n is at least 4 times the value of the minimal_stake constant. *) let test_supermajority_in_proposal there_is_a_winner () = + let open Lwt_result_syntax in let min_proposal_quorum = 0l in let initial_balance = 1L in - context_init - ~min_proposal_quorum - ~bootstrap_balances:[initial_balance; initial_balance; initial_balance] - 10 - () - >>=? fun (b, delegates) -> - Context.get_constants (B b) - >>=? fun {parametric = {minimal_stake; minimal_frozen_stake; _}; _} -> + let* b, delegates = + context_init + ~min_proposal_quorum + ~bootstrap_balances:[initial_balance; initial_balance; initial_balance] + 10 + () + in + let* {parametric = {minimal_stake; minimal_frozen_stake; _}; _} = + Context.get_constants (B b) + in let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in let del2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 1 in let del3 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 2 in @@ -865,59 +921,66 @@ let test_supermajority_in_proposal there_is_a_winner () = List.map (fun del -> Context.Contract.pkh del) [del1; del2; del3] in let policy = Block.Excluding pkhs in - Op.transaction - (B b) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 3) - del1 - minimal_stake - >>=? fun op1 -> - Op.transaction - (B b) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 4) - del2 - minimal_stake - >>=? fun op2 -> - (if there_is_a_winner then Test_tez.( *? ) minimal_stake 3L - else - Test_tez.( *? ) minimal_stake 2L - >>? Test_tez.( +? ) (Test_tez.of_mutez_exn initial_balance)) - >>?= fun bal3 -> - Op.transaction - (B b) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 5) - del3 - bal3 - >>=? fun op3 -> - Adaptive_issuance_helpers.stake (B b) del1 minimal_frozen_stake - >>=? fun op4 -> - Adaptive_issuance_helpers.stake (B b) del2 minimal_frozen_stake - >>=? fun op5 -> - Adaptive_issuance_helpers.stake (B b) del3 minimal_frozen_stake - >>=? fun op6 -> - Block.bake ~policy ~operations:[op1; op2; op3; op4; op5; op6] b >>=? fun b -> - bake_until_first_block_of_next_period ~policy b >>=? fun b -> + let* op1 = + Op.transaction + (B b) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 3) + del1 + minimal_stake + in + let* op2 = + Op.transaction + (B b) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 4) + del2 + minimal_stake + in + let*? bal3 = + if there_is_a_winner then Test_tez.( *? ) minimal_stake 3L + else + let open Result_syntax in + let* t = Test_tez.( *? ) minimal_stake 2L in + Test_tez.( +? ) (Test_tez.of_mutez_exn initial_balance) t + in + let* op3 = + Op.transaction + (B b) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 5) + del3 + bal3 + in + let* op4 = Adaptive_issuance_helpers.stake (B b) del1 minimal_frozen_stake in + let* op5 = Adaptive_issuance_helpers.stake (B b) del2 minimal_frozen_stake in + let* op6 = Adaptive_issuance_helpers.stake (B b) del3 minimal_frozen_stake in + let* b = Block.bake ~policy ~operations:[op1; op2; op3; op4; op5; op6] b in + let* b = bake_until_first_block_of_next_period ~policy b in (* make the proposals *) - Op.proposals (B b) del1 [protos.(0)] >>=? fun ops1 -> - Op.proposals (B b) del2 [protos.(0)] >>=? fun ops2 -> - Op.proposals (B b) del3 [protos.(1)] >>=? fun ops3 -> - Block.bake ~policy ~operations:[ops1; ops2; ops3] b >>=? fun b -> - bake_until_first_block_of_next_period ~policy b >>=? fun b -> + let* ops1 = Op.proposals (B b) del1 [protos.(0)] in + let* ops2 = Op.proposals (B b) del2 [protos.(0)] in + let* ops3 = Op.proposals (B b) del3 [protos.(1)] in + let* b = Block.bake ~policy ~operations:[ops1; ops2; ops3] b in + let* b = bake_until_first_block_of_next_period ~policy b in (* we remain in the proposal period when there is no winner, otherwise we move to the exploration period *) - (if there_is_a_winner then assert_period ~expected_kind:Exploration b __LOC__ - else assert_period ~expected_kind:Proposal b __LOC__) - >>=? fun () -> return_unit + let* () = + if there_is_a_winner then assert_period ~expected_kind:Exploration b __LOC__ + else assert_period ~expected_kind:Proposal b __LOC__ + in + return_unit (** After one voting period, if [has_quorum] then the period kind must have been the cooldown vote. Otherwise, it should have remained in place in the proposal period. *) let test_quorum_in_proposal has_quorum () = + let open Lwt_result_syntax in let total_tokens = 32_000_000_000_000L in let half_tokens = Int64.div total_tokens 2L in - context_init ~bootstrap_balances:[1L; half_tokens; half_tokens] 3 () - >>=? fun (b, delegates) -> - Context.get_constants (B b) - >>=? fun {parametric = {min_proposal_quorum; _}; _} -> + let* b, delegates = + context_init ~bootstrap_balances:[1L; half_tokens; half_tokens] 3 () + in + let* {parametric = {min_proposal_quorum; _}; _} = + Context.get_constants (B b) + in let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in let del2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 1 in let pkhs = List.map (fun del -> Context.Contract.pkh del) [del1; del2] in @@ -929,43 +992,48 @@ let test_quorum_in_proposal has_quorum () = let bal = Int64.(div (mul total_tokens quorum) 100_00L) |> Test_tez.of_mutez_exn in - Op.transaction (B b) del2 del1 bal >>=? fun op2 -> - Block.bake ~policy ~operation:op2 b >>=? fun b -> - Adaptive_issuance_helpers.stake (B b) del1 bal >>=? fun stake -> - Block.bake ~policy ~operation:stake b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> + let* op2 = Op.transaction (B b) del2 del1 bal in + let* b = Block.bake ~policy ~operation:op2 b in + let* stake = Adaptive_issuance_helpers.stake (B b) del1 bal in + let* b = Block.bake ~policy ~operation:stake b in + let* b = bake_until_first_block_of_next_period b in (* make the proposal *) - Op.proposals (B b) del1 [protos.(0)] >>=? fun operation -> - Block.bake ~policy ~operation b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> + let* operation = Op.proposals (B b) del1 [protos.(0)] in + let* b = Block.bake ~policy ~operation b in + let* b = bake_until_first_block_of_next_period b in (* we remain in the proposal period when there is no quorum, otherwise we move to the cooldown vote period *) - (if has_quorum then assert_period ~expected_kind:Exploration b __LOC__ - else assert_period ~expected_kind:Proposal b __LOC__) - >>=? fun () -> return_unit + let* () = + if has_quorum then assert_period ~expected_kind:Exploration b __LOC__ + else assert_period ~expected_kind:Proposal b __LOC__ + in + return_unit (** If a supermajority is reached, then the voting period must be reached. Otherwise, it remains in proposal period. *) let test_supermajority_in_exploration supermajority () = + let open Lwt_result_syntax in let min_proposal_quorum = Int32.(of_int @@ (100_00 / 100)) in - context_init ~min_proposal_quorum 100 () >>=? fun (b, delegates) -> + let* b, delegates = context_init ~min_proposal_quorum 100 () in let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in let proposal = protos.(0) in - Op.proposals (B b) del1 [proposal] >>=? fun operation -> - Block.bake ~operation b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> + let* operation = Op.proposals (B b) del1 [proposal] in + let* b = Block.bake ~operation b in + let* b = bake_until_first_block_of_next_period b in (* move to exploration *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Exploration b __LOC__ in (* assert our proposal won *) - (Context.Vote.get_current_proposal (B b) >>=? function - | Some v -> - if Protocol_hash.(equal proposal v) then return_unit - else failwith "%s - Wrong proposal" __LOC__ - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> + let* () = + let* v_opt = Context.Vote.get_current_proposal (B b) in + match v_opt with + | Some v -> + if Protocol_hash.(equal proposal v) then return_unit + else failwith "%s - Wrong proposal" __LOC__ + | None -> failwith "%s - Missing proposal" __LOC__ + in (* beginning of exploration period, denoted by _p2; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p2, _power_p2) -> + let* delegates_p2, _power_p2 = get_delegates_and_power_from_listings b in (* supermajority means [num_yays / (num_yays + num_nays) >= s_num / s_den], which is equivalent with [num_yays >= num_nays * s_num / (s_den - s_num)] *) let num_delegates = List.length delegates_p2 in @@ -977,61 +1045,73 @@ let test_supermajority_in_exploration supermajority () = let open Alpha_context in let nays_delegates, rest = List.split_n num_nays delegates_p2 in let yays_delegates, _ = List.split_n num_yays rest in - List.map_es (fun del -> Op.ballot (B b) del proposal Vote.Yay) yays_delegates - >>=? fun operations_yays -> - List.map_es (fun del -> Op.ballot (B b) del proposal Vote.Nay) nays_delegates - >>=? fun operations_nays -> + let* operations_yays = + List.map_es + (fun del -> Op.ballot (B b) del proposal Vote.Yay) + yays_delegates + in + let* operations_nays = + List.map_es + (fun del -> Op.ballot (B b) del proposal Vote.Nay) + nays_delegates + in let operations = operations_yays @ operations_nays in - Block.bake ~operations b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> - (if supermajority then assert_period ~expected_kind:Cooldown b __LOC__ - else assert_period ~expected_kind:Proposal b __LOC__) - >>=? fun () -> return_unit + let* b = Block.bake ~operations b in + let* b = bake_until_first_block_of_next_period b in + let* () = + if supermajority then assert_period ~expected_kind:Cooldown b __LOC__ + else assert_period ~expected_kind:Proposal b __LOC__ + in + return_unit (** Test also how the selection scales: all delegates propose max proposals. *) let test_no_winning_proposal num_delegates () = + let open Lwt_result_syntax in let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - context_init ~min_proposal_quorum num_delegates () >>=? fun (b, _) -> + let* b, _ = context_init ~min_proposal_quorum num_delegates () in (* beginning of proposal, denoted by _p1; take a snapshot of the active delegates and their voting power from listings *) - get_delegates_and_power_from_listings b >>=? fun (delegates_p1, _power_p1) -> + let* delegates_p1, _power_p1 = get_delegates_and_power_from_listings b in let open Alpha_context in let props = List.map (fun i -> protos.(i)) (1 -- Constants.max_proposals_per_delegate) in (* all delegates active in p1 propose the same proposals *) - List.map_es (fun del -> Op.proposals (B b) del props) delegates_p1 - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> + let* operations = + List.map_es (fun del -> Op.proposals (B b) del props) delegates_p1 + in + let* b = Block.bake ~operations b in (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* we stay in the same proposal period because no winning proposal *) - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> return_unit + let* () = assert_period ~expected_kind:Proposal b __LOC__ in + return_unit (** Vote to pass with maximum possible participation_ema (100%), it is sufficient for the vote quorum to be equal or greater than the maximum quorum cap. *) let test_quorum_capped_maximum num_delegates () = + let open Lwt_result_syntax in let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - context_init ~min_proposal_quorum num_delegates () >>=? fun (b, delegates) -> + let* b, delegates = context_init ~min_proposal_quorum num_delegates () in (* set the participation EMA to 100% *) - Context.Vote.set_participation_ema b 100_00l >>= fun b -> - Context.get_constants (B b) >>=? fun {parametric = {quorum_max; _}; _} -> + let*! b = Context.Vote.set_participation_ema b 100_00l in + let* {parametric = {quorum_max; _}; _} = Context.get_constants (B b) in (* proposal period *) let open Alpha_context in - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Proposal b __LOC__ in (* propose a new protocol *) let protocol = Protocol_hash.zero in let proposer = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in - Op.proposals (B b) proposer [protocol] >>=? fun operation -> - Block.bake ~operation b >>=? fun b -> + let* operation = Op.proposals (B b) proposer [protocol] in + let* b = Block.bake ~operation b in (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Exploration b __LOC__ in (* take percentage of the delegates equal or greater than quorum_max *) let minimum_to_pass = Float.of_int (List.length delegates) @@ -1041,11 +1121,12 @@ let test_quorum_capped_maximum num_delegates () = in let voters = List.take_n minimum_to_pass delegates in (* all voters vote for yays; no nays, so supermajority is satisfied *) - List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> + let* operations = + List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters + in + let* b = Block.bake ~operations b in (* skip to next period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* expect to move to cooldown because we have supermajority and enough quorum *) assert_period ~expected_kind:Cooldown b __LOC__ @@ -1053,25 +1134,26 @@ let test_quorum_capped_maximum num_delegates () = sufficient for the vote quorum to be equal or greater than the minimum quorum cap. *) let test_quorum_capped_minimum num_delegates () = + let open Lwt_result_syntax in let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - context_init ~min_proposal_quorum num_delegates () >>=? fun (b, delegates) -> + let* b, delegates = context_init ~min_proposal_quorum num_delegates () in (* set the participation EMA to 0% *) - Context.Vote.set_participation_ema b 0l >>= fun b -> - Context.get_constants (B b) >>=? fun {parametric = {quorum_min; _}; _} -> + let*! b = Context.Vote.set_participation_ema b 0l in + let* {parametric = {quorum_min; _}; _} = Context.get_constants (B b) in (* proposal period *) let open Alpha_context in - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Proposal b __LOC__ in (* propose a new protocol *) let protocol = Protocol_hash.zero in let proposer = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in - Op.proposals (B b) proposer [protocol] >>=? fun operation -> - Block.bake ~operation b >>=? fun b -> + let* operation = Op.proposals (B b) proposer [protocol] in + let* b = Block.bake ~operation b in (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + let* () = assert_period ~expected_kind:Exploration b __LOC__ in (* take percentage of the delegates equal or greater than quorum_min *) let minimum_to_pass = Float.of_int (List.length delegates) @@ -1081,11 +1163,12 @@ let test_quorum_capped_minimum num_delegates () = in let voters = List.take_n minimum_to_pass delegates in (* all voters vote for yays; no nays, so supermajority is satisfied *) - List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> + let* operations = + List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters + in + let* b = Block.bake ~operations b in (* skip to next period *) - bake_until_first_block_of_next_period b >>=? fun b -> + let* b = bake_until_first_block_of_next_period b in (* expect to move to cooldown because we have supermajority and enough quorum *) assert_period ~expected_kind:Cooldown b __LOC__ @@ -1099,12 +1182,14 @@ let get_voting_power block pkhash = the total voting power coincides with the addition of the voting powers of bakers *) let test_voting_power_updated_each_voting_period () = + let open Lwt_result_syntax in let init_bal1 = 80_000_000_000L in let init_bal2 = 48_000_000_000L in let init_bal3 = 40_000_000_000L in (* Create three accounts with different amounts *) - context_init ~bootstrap_balances:[init_bal1; init_bal2; init_bal3] 3 () - >>=? fun (genesis, contracts) -> + let* genesis, contracts = + context_init ~bootstrap_balances:[init_bal1; init_bal2; init_bal3] 3 () + in let con1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in let con2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 in let con3 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 2 in @@ -1114,108 +1199,127 @@ let test_voting_power_updated_each_voting_period () = let baker3 = Context.Contract.pkh con3 in (* Retrieve balance of con1 *) let open Test_tez in - Context.Contract.balance (B genesis) con1 >>=? fun balance1 -> - Context.Delegate.current_frozen_deposits (B genesis) baker1 - >>=? fun frozen_deposits1 -> - balance1 +? frozen_deposits1 >>?= fun full_balance1 -> - Assert.equal_tez ~loc:__LOC__ full_balance1 (of_mutez_exn init_bal1) - >>=? fun () -> + let* balance1 = Context.Contract.balance (B genesis) con1 in + let* frozen_deposits1 = + Context.Delegate.current_frozen_deposits (B genesis) baker1 + in + let*? full_balance1 = balance1 +? frozen_deposits1 in + let* () = + Assert.equal_tez ~loc:__LOC__ full_balance1 (of_mutez_exn init_bal1) + in (* Retrieve balance of con2 *) - Context.Contract.balance (B genesis) con2 >>=? fun balance2 -> - Context.Delegate.current_frozen_deposits (B genesis) baker2 - >>=? fun frozen_deposits2 -> - balance2 +? frozen_deposits2 >>?= fun full_balance2 -> - Assert.equal_tez ~loc:__LOC__ full_balance2 (of_mutez_exn init_bal2) - >>=? fun () -> + let* balance2 = Context.Contract.balance (B genesis) con2 in + let* frozen_deposits2 = + Context.Delegate.current_frozen_deposits (B genesis) baker2 + in + let*? full_balance2 = balance2 +? frozen_deposits2 in + let* () = + Assert.equal_tez ~loc:__LOC__ full_balance2 (of_mutez_exn init_bal2) + in (* Retrieve balance of con3 *) - Context.Contract.balance (B genesis) con3 >>=? fun balance3 -> - Context.Delegate.current_frozen_deposits (B genesis) baker3 - >>=? fun frozen_deposits3 -> - balance3 +? frozen_deposits3 >>?= fun full_balance3 -> - Assert.equal_tez ~loc:__LOC__ full_balance3 (of_mutez_exn init_bal3) - >>=? fun () -> + let* balance3 = Context.Contract.balance (B genesis) con3 in + let* frozen_deposits3 = + Context.Delegate.current_frozen_deposits (B genesis) baker3 + in + let*? full_balance3 = balance3 +? frozen_deposits3 in + let* () = + Assert.equal_tez ~loc:__LOC__ full_balance3 (of_mutez_exn init_bal3) + in (* Auxiliary assert_voting_power *) let assert_voting_power ~loc n block baker = - get_voting_power block baker >>=? fun voting_power -> + let* voting_power = get_voting_power block baker in Assert.equal_int64 ~loc n voting_power in (* Auxiliary assert_total_voting_power *) let assert_total_voting_power ~loc n block = - Context.get_total_voting_power (B block) >>=? fun total_voting_power -> + let* total_voting_power = Context.get_total_voting_power (B block) in Assert.equal_int64 ~loc n total_voting_power in let expected_power_of_baker_1 = Tez.to_mutez full_balance1 in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 genesis baker1 - >>=? fun () -> + let* () = + assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 genesis baker1 + in let expected_power_of_baker_2 = Tez.to_mutez full_balance2 in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 genesis baker2 - >>=? fun () -> + let* () = + assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 genesis baker2 + in (* Assert total voting power *) let expected_power_of_baker_3 = Tez.to_mutez full_balance3 in - assert_total_voting_power - ~loc:__LOC__ - Int64.( - add - (add expected_power_of_baker_1 expected_power_of_baker_2) - expected_power_of_baker_3) - genesis - >>=? fun () -> + let* () = + assert_total_voting_power + ~loc:__LOC__ + Int64.( + add + (add expected_power_of_baker_1 expected_power_of_baker_2) + expected_power_of_baker_3) + genesis + in (* Create policy that excludes baker1 and baker2 from baking *) let policy = Block.Excluding [baker1; baker2] in (* Transfer 30,000 tez from baker1 to baker2 *) let amount = Tez.of_mutez_exn 30_000_000_000L in - Op.transaction (B genesis) con1 con2 amount >>=? fun operation -> + let* operation = Op.transaction (B genesis) con1 con2 amount in (* Bake the block containing the transaction *) - Block.bake ~policy ~operation genesis >>=? fun block -> + let* block = Block.bake ~policy ~operation genesis in (* Retrieve balance of con1 *) - Context.Contract.balance (B block) con1 >>=? fun balance1 -> + let* balance1 = Context.Contract.balance (B block) con1 in (* Assert balance has changed by deducing the amount *) - of_mutez_exn init_bal1 -? amount >>?= fun balance1_after_deducing_amount -> - Context.Delegate.current_frozen_deposits (B block) baker1 - >>=? fun frozen_deposit1 -> - balance1_after_deducing_amount -? frozen_deposit1 - >>?= Assert.equal_tez ~loc:__LOC__ balance1 - >>=? fun () -> + let*? balance1_after_deducing_amount = of_mutez_exn init_bal1 -? amount in + let* frozen_deposit1 = + Context.Delegate.current_frozen_deposits (B block) baker1 + in + let* () = + let*? t = balance1_after_deducing_amount -? frozen_deposit1 in + Assert.equal_tez ~loc:__LOC__ balance1 t + in (* Retrieve balance of con2 *) - Context.Contract.balance (B block) con2 >>=? fun balance2 -> + let* balance2 = Context.Contract.balance (B block) con2 in (* Assert balance has changed by adding amount *) - of_mutez_exn init_bal2 +? amount >>?= fun balance2_after_adding_amount -> - Context.Delegate.current_frozen_deposits (B block) baker2 - >>=? fun frozen_deposit2 -> - balance2_after_adding_amount -? frozen_deposit2 - >>?= Assert.equal_tez ~loc:__LOC__ balance2 - >>=? fun () -> - Block.bake ~policy block >>=? fun block -> + let*? balance2_after_adding_amount = of_mutez_exn init_bal2 +? amount in + let* frozen_deposit2 = + Context.Delegate.current_frozen_deposits (B block) baker2 + in + let* () = + let*? t = balance2_after_adding_amount -? frozen_deposit2 in + Assert.equal_tez ~loc:__LOC__ balance2 t + in + let* block = Block.bake ~policy block in (* Assert voting power (and total) remains the same before next voting period *) - assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 - >>=? fun () -> - assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 - >>=? fun () -> - assert_voting_power ~loc:__LOC__ expected_power_of_baker_3 block baker3 - >>=? fun () -> - assert_total_voting_power - ~loc:__LOC__ - Int64.( - add - (add expected_power_of_baker_1 expected_power_of_baker_2) - expected_power_of_baker_3) - block - >>=? fun () -> - bake_until_first_block_of_next_period block >>=? fun block -> + let* () = + assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 + in + let* () = + assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 + in + let* () = + assert_voting_power ~loc:__LOC__ expected_power_of_baker_3 block baker3 + in + let* () = + assert_total_voting_power + ~loc:__LOC__ + Int64.( + add + (add expected_power_of_baker_1 expected_power_of_baker_2) + expected_power_of_baker_3) + block + in + let* block = bake_until_first_block_of_next_period block in (* Assert voting power of baker1 has decreased by [amount] *) let expected_power_of_baker_1 = Int64.sub expected_power_of_baker_1 (Tez.to_mutez amount) in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 - >>=? fun () -> + let* () = + assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 + in (* Assert voting power of baker2 has increased by [amount] *) let expected_power_of_baker_2 = Int64.add expected_power_of_baker_2 (Tez.to_mutez amount) in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 - >>=? fun () -> + let* () = + assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 + in (* Retrieve voting power of baker3 *) - get_voting_power block baker3 >>=? fun power -> + let* power = get_voting_power block baker3 in let power_of_baker_3 = power in (* Assert total voting power *) assert_total_voting_power