Tests: add test for switching unanimously to 'demo' protocol

This commit is contained in:
Guillem Rieu 2017-04-12 18:53:23 +02:00 committed by Grégoire Henry
parent 3c44f1dfba
commit 76b9cedcef
9 changed files with 254 additions and 7 deletions

View File

@ -132,6 +132,15 @@ test:proto_alpha:endorsement:
dependencies: dependencies:
- build - build
test:proto_alpha:vote:
stage: test
tags:
- tezos_builder
script:
- make -C test/proto_alpha run-test-vote
dependencies:
- build
test:basic.sh: test:basic.sh:
stage: test stage: test
tags: tags:

View File

@ -218,6 +218,14 @@ module Helpers = struct
b ~net ~source ~block ~slot () = b ~net ~source ~block ~slot () =
operations cctxt b ~net ~source operations cctxt b ~net ~source
Tezos_context.[Endorsement { block ; slot }] Tezos_context.[Endorsement { block ; slot }]
let proposals cctxt
b ~net ~source ~period ~proposals () =
operations cctxt b ~net ~source
Tezos_context.[Proposals { period ; proposals }]
let ballot cctxt
b ~net ~source ~period ~proposal ~ballot () =
operations cctxt b ~net ~source
Tezos_context.[Ballot { period ; proposal ; ballot }]
end end
module Dictator = struct module Dictator = struct
let operation cctxt let operation cctxt

View File

@ -269,6 +269,23 @@ module Helpers : sig
block:Block_hash.t -> block:Block_hash.t ->
slot:int -> slot:int ->
unit -> MBytes.t tzresult Lwt.t unit -> MBytes.t tzresult Lwt.t
val proposals:
Client_rpcs.config ->
block ->
net:Net_id.t ->
source:public_key ->
period:Voting_period.t ->
proposals:Hash.Protocol_hash.t list ->
unit -> MBytes.t tzresult Lwt.t
val ballot:
Client_rpcs.config ->
block ->
net:Net_id.t ->
source:public_key ->
period:Voting_period.t ->
proposal:Hash.Protocol_hash.t ->
ballot:Vote.ballot ->
unit -> MBytes.t tzresult Lwt.t
end end
module Anonymous : sig module Anonymous : sig
val operations: val operations:

View File

@ -5,6 +5,7 @@ TESTS := \
transaction \ transaction \
origination \ origination \
endorsement \ endorsement \
vote \
include ../Makefile.shared include ../Makefile.shared
@ -85,3 +86,22 @@ test-endorsement: ${LIB} ${TEST_CONNECTION_IMPLS:.ml=.cmx}
clean:: clean::
rm -f test-endorsement rm -f test-endorsement
############################################################################
## Vote
.PHONY:run-test-vote
run-test-vote:
@echo
./test-vote
TEST_CONNECTION_IMPLS := \
proto_alpha_helpers.ml \
test_vote.ml
test-vote: ${LIB} ${TEST_CONNECTION_IMPLS:.ml=.cmx}
@echo COMPILE $(notdir $@)
@${OCAMLOPT} -linkall -linkpkg ${OCAMLFLAGS} -o $@ $^
clean::
rm -f test-vote

View File

@ -32,17 +32,20 @@ let activate_alpha () =
(Activate Client_proto_main.protocol) (Activate Client_proto_main.protocol)
fitness dictator_sk fitness dictator_sk
let init () = let init ?(sandbox = "sandbox.json") () =
Random.self_init () ; Random.self_init () ;
Unix.chdir (Filename.dirname (Filename.dirname Sys.executable_name)) ; Unix.chdir (Filename.dirname (Filename.dirname Sys.executable_name)) ;
let pid = let pid =
Node_helpers.fork_node Node_helpers.fork_node
~port:rpc_config.port ~port:rpc_config.port
~sandbox:(Filename.dirname Sys.executable_name // "sandbox.json") ~sandbox:(Filename.dirname Sys.executable_name // sandbox)
() in () in
activate_alpha () >>=? fun hash -> activate_alpha () >>=? fun hash ->
return (pid, hash) return (pid, hash)
let level block =
Client_alpha.Client_proto_rpcs.Context.level rpc_config block
module Account = struct module Account = struct
type t = { type t = {
@ -237,6 +240,41 @@ module Account = struct
end end
module Protocol = struct
open Account
let inject_proposals ?async ?force ?(block = `Prevalidation) ~src:({ pk; sk } : Account.t) proposals =
Client_node_rpcs.Blocks.info rpc_config block >>=? fun block_info ->
Client_proto_rpcs.Context.next_level rpc_config block >>=? fun next_level ->
Client_proto_rpcs.Helpers.Forge.Delegate.proposals rpc_config block
~net:block_info.net_id
~source:pk
~period:next_level.voting_period
~proposals
() >>=? fun bytes ->
let signed_bytes = Environment.Ed25519.Signature.append sk bytes in
Client_node_rpcs.inject_operation
rpc_config ?async ?force signed_bytes >>=? fun oph ->
return oph
let inject_ballot ?async ?force ?(block = `Prevalidation) ~src:({ pk; sk } : Account.t) ~proposal ballot =
Client_node_rpcs.Blocks.info rpc_config block >>=? fun block_info ->
Client_proto_rpcs.Context.next_level rpc_config block >>=? fun next_level ->
Client_proto_rpcs.Helpers.Forge.Delegate.ballot rpc_config block
~net:block_info.net_id
~source:pk
~period:next_level.voting_period
~proposal
~ballot
() >>=? fun bytes ->
let signed_bytes = Environment.Ed25519.Signature.append sk bytes in
Client_node_rpcs.inject_operation
rpc_config ?async ?force signed_bytes >>=? fun oph ->
return oph
end
module Assert = struct module Assert = struct
include Assert include Assert
@ -335,6 +373,14 @@ module Assert = struct
| _ -> false) | _ -> false)
end end
let check_protocol ?msg ~block h =
Client_node_rpcs.Blocks.protocol rpc_config block >>=? fun block_proto ->
return @@ Assert.equal
?msg:(Assert.format_msg msg)
~prn:Protocol_hash.to_b58check
~eq:Protocol_hash.equal
block_proto h
end end
module Mining = struct module Mining = struct
@ -383,6 +429,7 @@ module Mining = struct
let inject_block let inject_block
block block
?force ?force
?proto_level
~priority ~priority
~timestamp ~timestamp
~fitness ~fitness
@ -391,6 +438,7 @@ module Mining = struct
operation_list = operation_list =
let block = match block with `Prevalidation -> `Head 0 | block -> block in let block = match block with `Prevalidation -> `Head 0 | block -> block in
Client_node_rpcs.Blocks.info rpc_config block >>=? fun bi -> Client_node_rpcs.Blocks.info rpc_config block >>=? fun bi ->
let proto_level = Utils.unopt ~default:bi.proto_level proto_level in
let seed_nonce_hash = Nonce.hash seed_nonce in let seed_nonce_hash = Nonce.hash seed_nonce in
Client_proto_rpcs.Context.next_level rpc_config block >>=? fun level -> Client_proto_rpcs.Context.next_level rpc_config block >>=? fun level ->
let operations_hash = let operations_hash =
@ -400,7 +448,7 @@ module Mining = struct
{ Store.Block_header.net_id = bi.net_id ; predecessor = bi.hash ; { Store.Block_header.net_id = bi.net_id ; predecessor = bi.hash ;
timestamp ; fitness ; operations_hash ; timestamp ; fitness ; operations_hash ;
level = Raw_level.to_int32 level.level ; level = Raw_level.to_int32 level.level ;
proto_level = 1 } in proto_level } in
mine_stamp mine_stamp
block src_sk shell priority seed_nonce_hash >>=? fun proof_of_work_nonce -> block src_sk shell priority seed_nonce_hash >>=? fun proof_of_work_nonce ->
Client_proto_rpcs.Helpers.Forge.block rpc_config Client_proto_rpcs.Helpers.Forge.block rpc_config
@ -411,7 +459,7 @@ module Mining = struct
~fitness ~fitness
~operations_hash ~operations_hash
~level:level.level ~level:level.level
~proto_level:1 ~proto_level
~priority ~priority
~seed_nonce_hash ~seed_nonce_hash
~proof_of_work_nonce ~proof_of_work_nonce
@ -424,7 +472,8 @@ module Mining = struct
let mine let mine
?(force = false) ?(force = false)
?(operations = []) ?(operations = [])
~fitness_gap ?(fitness_gap = 1)
?proto_level
contract contract
block = block =
Client_mining_blocks.info rpc_config block >>=? fun bi -> Client_mining_blocks.info rpc_config block >>=? fun bi ->
@ -444,6 +493,7 @@ module Mining = struct
Int64.add fitness (Int64.of_int fitness_gap) in Int64.add fitness (Int64.of_int fitness_gap) in
inject_block inject_block
~force ~force
?proto_level
~priority ~priority
~timestamp ~timestamp
~fitness ~fitness

View File

@ -11,11 +11,13 @@ open Client_embedded_proto_alpha
open Tezos_context open Tezos_context
open Client_alpha open Client_alpha
val init : unit -> (int * Block_hash.t) tzresult Lwt.t val init : ?sandbox:string -> unit -> (int * Block_hash.t) tzresult Lwt.t
(** [init ()] sets up the test environment, and return the PID of (** [init ()] sets up the test environment, and return the PID of
forked Tezos node and the block info of the block from where the forked Tezos node and the block info of the block from where the
tests will begin. *) tests will begin. *)
val level : Client_proto_rpcs.block -> Tezos_context.Level.t tzresult Lwt.t
module Account : sig module Account : sig
type t = { type t = {
@ -112,6 +114,7 @@ module Mining : sig
val inject_block : val inject_block :
Client_node_rpcs.Blocks.block -> Client_node_rpcs.Blocks.block ->
?force:bool -> ?force:bool ->
?proto_level:int ->
priority:int -> priority:int ->
timestamp:Time.t -> timestamp:Time.t ->
fitness:Fitness.t -> fitness:Fitness.t ->
@ -122,7 +125,8 @@ module Mining : sig
val mine : val mine :
?force:bool -> ?force:bool ->
?operations:Operation_hash.t list -> ?operations:Operation_hash.t list ->
fitness_gap:int -> ?fitness_gap:int ->
?proto_level:int ->
Account.t -> Account.t ->
Client_node_rpcs.Blocks.block -> Client_node_rpcs.Blocks.block ->
Block_hash.t tzresult Lwt.t Block_hash.t tzresult Lwt.t
@ -155,6 +159,27 @@ module Endorse : sig
end end
module Protocol : sig
val inject_proposals :
?async:bool ->
?force:bool ->
?block:Client_node_rpcs.Blocks.block ->
src:Account.t ->
Hash.Protocol_hash.t list ->
Hash.Operation_list_hash.elt tzresult Lwt.t
val inject_ballot :
?async:bool ->
?force:bool ->
?block:Client_node_rpcs.Blocks.block ->
src:Account.t ->
proposal:Hash.Protocol_hash.t ->
Vote.ballot ->
Hash.Operation_list_hash.elt tzresult Lwt.t
end
module Assert : sig module Assert : sig
include module type of Assert include module type of Assert
@ -191,6 +216,10 @@ module Assert : sig
val invalid_endorsement_slot : msg:string -> 'a tzresult -> unit val invalid_endorsement_slot : msg:string -> 'a tzresult -> unit
val check_protocol :
?msg:string -> block:Client_node_rpcs.Blocks.block ->
Hash.Protocol_hash.t -> unit tzresult Lwt.t
end end
val rpc_config: Client_rpcs.config val rpc_config: Client_rpcs.config

View File

@ -0,0 +1,16 @@
{
"genesis_pubkey":
"edpkuSLWfVU1Vq7Jg9FucPyKmma6otcMHac9zG4oU1KMHSTBpJuGQ2",
"bootstrap_keys": [
"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav",
"edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9",
"edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV",
"edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU",
"edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n"
],
"slot_durations" : [ 1, 0 ],
"cycle_length" : 4,
"voting_period_length" : 2,
"time_before_reward" : 1,
"first_free_mining_slot" : 4
}

View File

@ -0,0 +1,90 @@
(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2016. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
open Client_embedded_proto_alpha
open Tezos_context
open Proto_alpha_helpers
let demo_protocol =
Protocol_hash.of_b58check_exn
"ProtoDemoDemoDemoDemoDemoDemoDemoDemoDemoDemoD3c8k9"
let print_level head =
level (`Hash head) >>=? fun lvl ->
return @@ Format.eprintf "voting_period = %a.%ld@."
Voting_period.pp lvl.voting_period lvl.voting_period_position
let run_change_to_demo_proto block ({ b1 ; b2 ; b3 ; b4 ; b5 } : Account.bootstrap_accounts) =
Mining.mine b1 block >>=? fun head ->
Format.eprintf "Entering `Proposal` voting period@.";
Mining.mine b2 (`Hash head) >>=? fun head ->
(* 1. Propose the 'demo' protocol as b1 (during the Proposal period) *)
Protocol.inject_proposals
~force:true
~block:(`Hash head)
~src:b1
[demo_protocol] >>=? fun oph ->
(* Mine blocks to switch to next vote period (Testing_vote) *)
Mining.mine ~operations:[oph] b3 (`Hash head) >>=? fun head ->
Format.eprintf "Entering `Testing_vote` voting period@.";
Mining.mine b4 (`Hash head) >>=? fun head ->
(* 2. Vote unanimously for a proposal *)
let vote_for_demo ~src ~block ballot =
Protocol.inject_ballot
~force:true
~block
~src
~proposal:demo_protocol
ballot
in
let all_accounts = [b1; b2; b3; b4; b5] in
map_s (fun src -> vote_for_demo ~src ~block:(`Hash head) Vote.Yay)
all_accounts >>=? fun operations ->
(* Mine blocks to switch to next vote period (Testing) *)
Mining.mine ~operations b5 (`Hash head) >>=? fun head ->
Format.eprintf "Entering `Testing` voting period@.";
Mining.mine b1 (`Hash head) >>=? fun head ->
(* 3. Test the proposed protocol *)
(* Mine blocks to switch to next vote period (Promote_vote) *)
Mining.mine b2 (`Hash head) >>=? fun head ->
Format.eprintf "Entering `Promote_vote` voting period@.";
Mining.mine b3 (`Hash head) >>=? fun head ->
(* 4. Vote unanimously for promoting the protocol *)
map_s (fun src -> vote_for_demo ~src ~block:(`Hash head) Vote.Yay)
all_accounts >>=? fun operations ->
(* Mine blocks to switch to end the vote cycle (back to Proposal) *)
Format.eprintf "Switching to `demo` protocol@.";
Mining.mine ~operations b4 (`Hash head) >>=? fun head ->
Mining.mine ~proto_level:2 b5 (`Hash head) >>=? fun head ->
Assert.check_protocol ~msg:__LOC__ ~block:(`Hash head) demo_protocol >>=? fun () ->
return (`Hash head)
let change_to_demo_proto () =
init ~sandbox:"sandbox-vote.json" () >>=? fun (_node_pid, hash) ->
run_change_to_demo_proto (`Hash hash) Account.bootstrap_accounts >>=? fun _blkh ->
return ()
let tests = [
"change_to_demo_proto", (fun _ -> change_to_demo_proto ()) ;
]
let () =
Test.run "amendment." tests

View File

@ -0,0 +1,8 @@
(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2016. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)