2016-10-12 17:00:19 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Copyright (c) 2014 - 2016. *)
|
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
open Hash
|
|
|
|
open Error_monad
|
|
|
|
|
|
|
|
let (//) = Filename.concat
|
|
|
|
|
|
|
|
(** Basic blocks *)
|
|
|
|
|
|
|
|
let genesis_block =
|
2017-04-05 11:54:21 +04:00
|
|
|
Block_hash.of_b58check_exn
|
2017-02-19 21:22:32 +04:00
|
|
|
"BLockGenesisGenesisGenesisGenesisGenesisGeneskvg68z"
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let genesis_protocol =
|
2017-04-05 11:54:21 +04:00
|
|
|
Protocol_hash.of_b58check_exn
|
2017-02-19 21:22:32 +04:00
|
|
|
"ProtoDemoDemoDemoDemoDemoDemoDemoDemoDemoDemoD3c8k9"
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let genesis_time =
|
|
|
|
Time.of_seconds 0L
|
|
|
|
|
|
|
|
module Proto = (val Updater.get_exn genesis_protocol)
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
let genesis : State.Net.genesis = {
|
|
|
|
time = genesis_time ;
|
2016-09-08 21:13:10 +04:00
|
|
|
block = genesis_block ;
|
|
|
|
protocol = genesis_protocol ;
|
|
|
|
}
|
|
|
|
|
2017-03-31 15:04:05 +04:00
|
|
|
let net_id = Net_id.of_block_hash genesis_block
|
2017-02-24 20:17:53 +04:00
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
let incr_fitness fitness =
|
|
|
|
let new_fitness =
|
|
|
|
match fitness with
|
2017-04-10 14:14:11 +04:00
|
|
|
| [ fitness ] ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Pervasives.(
|
|
|
|
Data_encoding.Binary.of_bytes Data_encoding.int64 fitness
|
2017-01-23 14:09:33 +04:00
|
|
|
|> Utils.unopt ~default:0L
|
2016-09-30 13:43:50 +04:00
|
|
|
|> Int64.succ
|
|
|
|
|> Data_encoding.Binary.to_bytes Data_encoding.int64
|
|
|
|
)
|
2016-09-08 21:13:10 +04:00
|
|
|
| _ -> Data_encoding.Binary.to_bytes Data_encoding.int64 1L
|
|
|
|
in
|
2017-04-10 14:14:11 +04:00
|
|
|
[ new_fitness ]
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let incr_timestamp timestamp =
|
2017-02-24 20:17:53 +04:00
|
|
|
Time.add timestamp (Int64.add 1L (Random.int64 10L))
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let operation op =
|
2017-04-19 21:21:23 +04:00
|
|
|
let op : Operation.t = {
|
2017-02-24 20:17:53 +04:00
|
|
|
shell = { net_id } ;
|
2016-09-30 13:43:50 +04:00
|
|
|
proto = MBytes.of_string op ;
|
2016-09-08 21:13:10 +04:00
|
|
|
} in
|
2017-04-19 21:21:23 +04:00
|
|
|
Operation.hash op,
|
2016-09-08 21:13:10 +04:00
|
|
|
op,
|
2017-04-19 21:21:23 +04:00
|
|
|
Data_encoding.Binary.to_bytes Operation.encoding op
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-04-19 21:21:23 +04:00
|
|
|
let block _state ?(operations = []) pred_hash pred name : Block_header.t =
|
2017-04-10 19:06:11 +04:00
|
|
|
let operations_hash =
|
2017-03-30 15:16:21 +04:00
|
|
|
Operation_list_list_hash.compute
|
|
|
|
[Operation_list_hash.compute operations] in
|
2017-04-19 21:21:23 +04:00
|
|
|
let fitness = incr_fitness pred.Block_header.shell.fitness in
|
2017-02-24 20:17:53 +04:00
|
|
|
let timestamp = incr_timestamp pred.shell.timestamp in
|
2016-09-08 21:13:10 +04:00
|
|
|
{ shell = {
|
|
|
|
net_id = pred.shell.net_id ;
|
2017-04-10 15:01:22 +04:00
|
|
|
level = Int32.succ pred.shell.level ;
|
2017-04-12 20:22:40 +04:00
|
|
|
proto_level = pred.shell.proto_level ;
|
2016-09-08 21:13:10 +04:00
|
|
|
predecessor = pred_hash ;
|
2017-04-10 19:06:11 +04:00
|
|
|
timestamp ; operations_hash ; fitness } ;
|
2016-09-08 21:13:10 +04:00
|
|
|
proto = MBytes.of_string name ;
|
|
|
|
}
|
|
|
|
|
2017-04-05 20:24:26 +04:00
|
|
|
let equal_operation ?msg op1 op2 =
|
|
|
|
let msg = Assert.format_msg msg in
|
|
|
|
let eq op1 op2 =
|
|
|
|
match op1, op2 with
|
|
|
|
| None, None -> true
|
|
|
|
| Some op1, Some op2 ->
|
2017-04-19 21:21:23 +04:00
|
|
|
Operation.equal op1 op2
|
2017-04-05 20:24:26 +04:00
|
|
|
| _ -> false in
|
|
|
|
let prn = function
|
|
|
|
| None -> "none"
|
2017-04-19 21:21:23 +04:00
|
|
|
| Some op -> Hash.Operation_hash.to_hex (Operation.hash op) in
|
2017-04-05 20:24:26 +04:00
|
|
|
Assert.equal ?msg ~prn ~eq op1 op2
|
|
|
|
|
|
|
|
let equal_block ?msg st1 st2 =
|
|
|
|
let msg = Assert.format_msg msg in
|
|
|
|
let eq st1 st2 =
|
|
|
|
match st1, st2 with
|
|
|
|
| None, None -> true
|
2017-04-19 21:21:23 +04:00
|
|
|
| Some st1, Some st2 -> Block_header.equal st1 st2
|
2017-04-05 20:24:26 +04:00
|
|
|
| _ -> false in
|
|
|
|
let prn = function
|
|
|
|
| None -> "none"
|
|
|
|
| Some st ->
|
2017-04-19 21:21:23 +04:00
|
|
|
Hash.Block_hash.to_hex (Block_header.hash st) in
|
2017-04-05 20:24:26 +04:00
|
|
|
Assert.equal ?msg ~prn ~eq st1 st2
|
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
let build_chain state tbl otbl pred names =
|
|
|
|
Lwt_list.fold_left_s
|
|
|
|
(fun (pred_hash, pred) name ->
|
|
|
|
begin
|
2017-04-05 20:24:26 +04:00
|
|
|
let oph, op, _bytes = operation name in
|
2017-03-30 15:16:21 +04:00
|
|
|
State.Operation.store state oph op >>= fun created ->
|
2017-02-24 20:17:53 +04:00
|
|
|
Assert.is_true ~msg:__LOC__ created ;
|
|
|
|
State.Operation.read_opt state oph >>= fun op' ->
|
2017-04-05 20:24:26 +04:00
|
|
|
equal_operation ~msg:__LOC__ (Some op) op' ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.mark_invalid state oph [] >>= fun store_invalid ->
|
|
|
|
Assert.is_true ~msg:__LOC__ store_invalid ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Hashtbl.add otbl name (oph, Error []) ;
|
|
|
|
let block = block ~operations:[oph] state pred_hash pred name in
|
2017-04-19 21:21:23 +04:00
|
|
|
let hash = Block_header.hash block in
|
2017-03-30 15:16:21 +04:00
|
|
|
State.Block_header.store state hash block >>= fun created ->
|
|
|
|
Assert.is_true ~msg:__LOC__ created ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Block_header.read_opt state hash >>= fun block' ->
|
2017-04-05 20:24:26 +04:00
|
|
|
equal_block ~msg:__LOC__ (Some block) block' ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Block_header.mark_invalid state hash [] >>= fun store_invalid ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.is_true ~msg:__LOC__ store_invalid ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Hashtbl.add tbl name (hash, block) ;
|
|
|
|
return (hash, block)
|
|
|
|
end >>= function
|
|
|
|
| Ok v -> Lwt.return v
|
|
|
|
| Error err ->
|
|
|
|
Error_monad.pp_print_error Format.err_formatter err ;
|
|
|
|
assert false)
|
|
|
|
pred
|
|
|
|
names >>= fun _ ->
|
|
|
|
Lwt.return ()
|
|
|
|
|
2017-04-05 20:24:26 +04:00
|
|
|
let block _state ?(operations = []) (pred: State.Valid_block.t) name
|
2017-04-19 21:21:23 +04:00
|
|
|
: Block_header.t =
|
2017-04-10 19:06:11 +04:00
|
|
|
let operations_hash =
|
2017-03-30 15:16:21 +04:00
|
|
|
Operation_list_list_hash.compute
|
|
|
|
[Operation_list_hash.compute operations] in
|
2016-09-08 21:13:10 +04:00
|
|
|
let fitness = incr_fitness pred.fitness in
|
|
|
|
let timestamp = incr_timestamp pred.timestamp in
|
|
|
|
{ shell = { net_id = pred.net_id ;
|
2017-04-10 15:01:22 +04:00
|
|
|
level = Int32.succ pred.level ;
|
2017-04-12 20:22:40 +04:00
|
|
|
proto_level = pred.proto_level ;
|
2016-09-08 21:13:10 +04:00
|
|
|
predecessor = pred.hash ;
|
2017-04-10 19:06:11 +04:00
|
|
|
timestamp ; operations_hash ; fitness } ;
|
2016-09-08 21:13:10 +04:00
|
|
|
proto = MBytes.of_string name ;
|
|
|
|
}
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
let build_valid_chain state tbl vtbl otbl pred names =
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt_list.fold_left_s
|
|
|
|
(fun pred name ->
|
|
|
|
begin
|
2017-04-05 20:24:26 +04:00
|
|
|
let oph, op, _bytes = operation name in
|
2017-03-30 15:16:21 +04:00
|
|
|
State.Operation.store state oph op >>= fun created ->
|
2017-02-24 20:17:53 +04:00
|
|
|
Assert.is_true ~msg:__LOC__ created ;
|
|
|
|
State.Operation.read_opt state oph >>= fun op' ->
|
2017-04-05 20:24:26 +04:00
|
|
|
equal_operation ~msg:__LOC__ (Some op) op' ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Hashtbl.add otbl name (oph, Ok op) ;
|
|
|
|
let block = block state ~operations:[oph] pred name in
|
2017-04-19 21:21:23 +04:00
|
|
|
let hash = Tezos_data.Block_header.hash block in
|
2017-03-30 15:16:21 +04:00
|
|
|
State.Block_header.store state hash block >>= fun created ->
|
|
|
|
Assert.is_true ~msg:__LOC__ created ;
|
|
|
|
State.Operation_list.store_all state hash [[oph]] >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Block_header.read_opt state hash >>= fun block' ->
|
2017-04-05 20:24:26 +04:00
|
|
|
equal_block ~msg:__LOC__ (Some block) block' ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Hashtbl.add tbl name (hash, block) ;
|
2016-10-20 20:54:16 +04:00
|
|
|
begin
|
|
|
|
Proto.begin_application
|
|
|
|
~predecessor_context: pred.context
|
|
|
|
~predecessor_timestamp: pred.timestamp
|
2017-04-10 14:14:11 +04:00
|
|
|
~predecessor_fitness: pred.fitness
|
2016-10-20 20:54:16 +04:00
|
|
|
block >>=? fun vstate ->
|
|
|
|
(* no operations *)
|
|
|
|
Proto.finalize_block vstate
|
|
|
|
end >>=? fun ctxt ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.store state hash ctxt >>=? fun _vblock ->
|
|
|
|
State.Valid_block.read state hash >>=? fun vblock ->
|
2016-09-08 21:13:10 +04:00
|
|
|
Hashtbl.add vtbl name vblock ;
|
|
|
|
return vblock
|
|
|
|
end >>= function
|
|
|
|
| Ok v -> Lwt.return v
|
|
|
|
| Error err ->
|
|
|
|
Error_monad.pp_print_error Format.err_formatter err ;
|
|
|
|
assert false)
|
|
|
|
pred
|
|
|
|
names >>= fun _ ->
|
|
|
|
Lwt.return ()
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
let build_example_tree net =
|
2016-09-08 21:13:10 +04:00
|
|
|
let tbl = Hashtbl.create 23 in
|
|
|
|
let vtbl = Hashtbl.create 23 in
|
|
|
|
let otbl = Hashtbl.create 23 in
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.genesis net >>= fun genesis ->
|
2017-03-22 20:21:52 +04:00
|
|
|
State.Block_header.read_exn net genesis.hash >>= fun genesis_header ->
|
2017-02-24 20:17:53 +04:00
|
|
|
Hashtbl.add vtbl "Genesis" genesis ;
|
2017-03-22 20:21:52 +04:00
|
|
|
Hashtbl.add tbl "Genesis" (genesis.hash, genesis_header ) ;
|
2016-09-08 21:13:10 +04:00
|
|
|
let chain = [ "A1" ; "A2" ; "A3" ; "A4" ; "A5" ; "A6" ; "A7" ; "A8" ] in
|
2017-02-24 20:17:53 +04:00
|
|
|
build_valid_chain net tbl vtbl otbl genesis chain >>= fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
let a3 = Hashtbl.find vtbl "A3" in
|
|
|
|
let chain = [ "B1" ; "B2" ; "B3" ; "B4" ; "B5" ; "B6" ; "B7" ; "B8" ] in
|
2017-02-24 20:17:53 +04:00
|
|
|
build_valid_chain net tbl vtbl otbl a3 chain >>= fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
let b7 = Hashtbl.find tbl "B7" in
|
|
|
|
let chain = [ "C1" ; "C2" ; "C3" ; "C4" ; "C5" ; "C6" ; "C7" ; "C8" ] in
|
2017-02-24 20:17:53 +04:00
|
|
|
build_chain net tbl otbl b7 chain >>= fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
let pending_op = "PP" in
|
2017-04-05 20:24:26 +04:00
|
|
|
let oph, op, _bytes = operation pending_op in
|
2017-03-30 15:16:21 +04:00
|
|
|
State.Operation.store net oph op >>= fun _ ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.read_opt net oph >>= fun op' ->
|
2017-04-05 20:24:26 +04:00
|
|
|
equal_operation ~msg:__LOC__ (Some op) op' ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Hashtbl.add otbl pending_op (oph, Ok op) ;
|
|
|
|
Lwt.return (tbl, vtbl, otbl)
|
|
|
|
|
|
|
|
type state = {
|
2017-04-19 21:21:23 +04:00
|
|
|
block: (string, Block_hash.t * Block_header.t) Hashtbl.t ;
|
|
|
|
operation: (string, Operation_hash.t * Operation.t tzresult) Hashtbl.t ;
|
2016-09-08 21:13:10 +04:00
|
|
|
vblock: (string, State.Valid_block.t) Hashtbl.t ;
|
|
|
|
state: State.t ;
|
|
|
|
net: State.Net.t ;
|
2017-02-24 20:17:53 +04:00
|
|
|
init: unit -> State.t tzresult Lwt.t;
|
2016-09-08 21:13:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
let block s = Hashtbl.find s.block
|
|
|
|
let vblock s = Hashtbl.find s.vblock
|
|
|
|
let operation s = Hashtbl.find s.operation
|
|
|
|
|
|
|
|
exception Found of string
|
|
|
|
let rev_find s h =
|
|
|
|
try
|
|
|
|
Hashtbl.iter (fun k (bh,_) ->
|
|
|
|
if Block_hash.equal bh h then raise (Found k))
|
|
|
|
s.block ;
|
|
|
|
Format.asprintf "genesis(%a)" Block_hash.pp_short h
|
|
|
|
with Found s -> s
|
|
|
|
|
|
|
|
let blocks s =
|
2017-02-24 20:17:53 +04:00
|
|
|
Hashtbl.fold (fun k v acc -> (k,v) :: acc) s.block []
|
|
|
|
|> List.sort Pervasives.compare
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let vblocks s =
|
2017-02-24 20:17:53 +04:00
|
|
|
Hashtbl.fold (fun k v acc -> (k,v) :: acc) s.vblock []
|
|
|
|
|> List.sort Pervasives.compare
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let operations s =
|
2017-02-24 20:17:53 +04:00
|
|
|
Hashtbl.fold (fun k v acc -> (k,v) :: acc) s.operation []
|
|
|
|
|> List.sort Pervasives.compare
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let wrap_state_init f base_dir =
|
|
|
|
begin
|
|
|
|
let store_root = base_dir // "store" in
|
|
|
|
let context_root = base_dir // "context" in
|
|
|
|
let init () =
|
|
|
|
State.read
|
|
|
|
~store_root
|
|
|
|
~context_root
|
|
|
|
() in
|
2017-02-24 20:17:53 +04:00
|
|
|
init () >>=? fun state ->
|
|
|
|
State.Net.create state genesis >>= fun net ->
|
|
|
|
build_example_tree net >>= fun (block, vblock, operation) ->
|
2017-04-05 20:24:26 +04:00
|
|
|
f { state ; net ; block ; vblock ; operation ; init } >>=? fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
return ()
|
2017-03-07 12:51:11 +04:00
|
|
|
end
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-04-05 20:24:26 +04:00
|
|
|
let test_init (_ : state) =
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let test_read_operation (s: state) =
|
|
|
|
Lwt_list.iter_s (fun (name, (oph, op)) ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.invalid s.net oph >>= function
|
|
|
|
| Some err ->
|
|
|
|
begin match op with
|
|
|
|
| Ok _ ->
|
|
|
|
Assert.fail_msg "Incorrect invalid operation read %s" name
|
|
|
|
| Error e ->
|
|
|
|
if e <> err then
|
|
|
|
Assert.fail_msg "Incorrect operation read %s" name ;
|
|
|
|
Lwt.return_unit
|
|
|
|
end
|
2016-09-08 21:13:10 +04:00
|
|
|
| None ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.read_opt s.net oph >>= function
|
|
|
|
| None ->
|
|
|
|
Assert.fail_msg "Cannot read block %s" name
|
|
|
|
| Some data ->
|
|
|
|
begin match op with
|
|
|
|
| Error _ ->
|
|
|
|
Assert.fail_msg "Incorrect valid operation read %s" name
|
|
|
|
| Ok op ->
|
2017-04-19 21:21:23 +04:00
|
|
|
if op.Operation.proto <> data.proto then
|
2017-02-24 20:17:53 +04:00
|
|
|
Assert.fail_msg "Incorrect operation read %s %s" name
|
2017-04-19 21:21:23 +04:00
|
|
|
(MBytes.to_string data.Operation.proto) ;
|
2017-02-24 20:17:53 +04:00
|
|
|
Lwt.return_unit
|
|
|
|
end)
|
2016-09-08 21:13:10 +04:00
|
|
|
(operations s) >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State. *)
|
|
|
|
|
|
|
|
let test_read_block (s: state) =
|
|
|
|
Lwt_list.iter_s (fun (name, (hash, block)) ->
|
|
|
|
begin
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Block_header.read_opt s.net hash >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| None ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Cannot read block %s" name
|
2017-02-24 20:17:53 +04:00
|
|
|
| Some block' ->
|
2017-04-19 21:21:23 +04:00
|
|
|
if not (Block_header.equal block block') then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Error while reading block %s" name ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return_unit
|
|
|
|
end >>= fun () ->
|
|
|
|
let vblock =
|
|
|
|
try Some (vblock s name)
|
|
|
|
with Not_found -> None in
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.read s.net hash >>= function
|
|
|
|
| Error _ ->
|
2016-09-08 21:13:10 +04:00
|
|
|
if vblock <> None then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Error while reading valid block %s" name ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return_unit
|
2017-02-24 20:17:53 +04:00
|
|
|
| Ok _vblock' ->
|
2016-09-08 21:13:10 +04:00
|
|
|
match vblock with
|
|
|
|
| None ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Error while reading invalid block %s" name
|
2016-09-08 21:13:10 +04:00
|
|
|
| Some _vblock ->
|
|
|
|
Lwt.return_unit
|
|
|
|
) (blocks s) >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.path *)
|
|
|
|
|
|
|
|
let rec compare_path p1 p2 = match p1, p2 with
|
|
|
|
| [], [] -> true
|
|
|
|
| h1 :: p1, h2 :: p2 -> Block_hash.equal h1 h2 && compare_path p1 p2
|
|
|
|
| _ -> false
|
|
|
|
|
|
|
|
let test_path (s: state) =
|
|
|
|
let check_path h1 h2 p2 =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Block_header.Helpers.path s.net (fst @@ block s h1) (fst @@ block s h2) >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| Error _ ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "cannot compute path %s -> %s" h1 h2
|
2016-09-08 21:13:10 +04:00
|
|
|
| Ok p1 ->
|
2017-02-24 20:17:53 +04:00
|
|
|
let p1 = List.map (fun b -> fst b) p1 in
|
2016-09-08 21:13:10 +04:00
|
|
|
let p2 = List.map (fun b -> fst (block s b)) p2 in
|
2016-09-30 13:43:50 +04:00
|
|
|
if not (compare_path p1 p2) then
|
|
|
|
Assert.fail_msg "bad path %s -> %s" h1 h2 ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return_unit in
|
2017-02-24 20:17:53 +04:00
|
|
|
check_path "Genesis" "Genesis" [] >>= fun () ->
|
|
|
|
check_path "A1" "A1" [] >>= fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
check_path "A2" "A6" ["A3"; "A4"; "A5"; "A6"] >>= fun () ->
|
|
|
|
check_path "B2" "B6" ["B3"; "B4"; "B5"; "B6"] >>= fun () ->
|
|
|
|
check_path "A1" "B3" ["A2"; "A3"; "B1"; "B2"; "B3"] >>= fun () ->
|
|
|
|
check_path "A1" "C2" ["A2"; "A3"; "B1"; "B2"; "B3" ; "B4" ;
|
|
|
|
"B5" ; "B6" ; "B7" ; "C1" ; "C2" ] >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let test_valid_path (s: state) =
|
|
|
|
let check_path h1 h2 p2 =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Helpers.path s.net (vblock s h1) (vblock s h2) >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| None ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "cannot compute path %s -> %s" h1 h2 ;
|
2016-09-08 21:13:10 +04:00
|
|
|
| Some (p: State.Valid_block.t list) ->
|
|
|
|
let p = List.map (fun b -> b.State.Valid_block.hash) p in
|
|
|
|
let p2 = List.map (fun b -> (vblock s b).hash) p2 in
|
2016-09-30 13:43:50 +04:00
|
|
|
if not (compare_path p p2) then
|
|
|
|
Assert.fail_msg "bad path %s -> %s" h1 h2 ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return_unit in
|
2017-02-24 20:17:53 +04:00
|
|
|
check_path "Genesis" "Genesis" [] >>= fun () ->
|
|
|
|
check_path "A1" "A1" [] >>= fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
check_path "A2" "A6" ["A3"; "A4"; "A5"; "A6"] >>= fun () ->
|
|
|
|
check_path "B2" "B6" ["B3"; "B4"; "B5"; "B6"] >>= fun () ->
|
|
|
|
check_path "A1" "B3" ["A2"; "A3"; "B1"; "B2"; "B3"] >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.ancestor *)
|
|
|
|
|
|
|
|
let test_ancestor s =
|
|
|
|
let check_ancestor h1 h2 expected =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Block_header.Helpers.common_ancestor
|
|
|
|
s.net (fst @@ block s h1) (fst @@ block s h2) >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| Error _ ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Cannot compure ancestor for %s %s" h1 h2 ;
|
2017-02-24 20:17:53 +04:00
|
|
|
| Ok (a, _) ->
|
2016-09-08 21:13:10 +04:00
|
|
|
if not (Block_hash.equal a (fst expected)) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg
|
|
|
|
"bad ancestor %s %s: found %s, expected %s"
|
|
|
|
h1 h2 (rev_find s a) (rev_find s @@ fst expected) ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return_unit in
|
|
|
|
let check_valid_ancestor h1 h2 expected =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Helpers.common_ancestor
|
|
|
|
s.net (vblock s h1) (vblock s h2) >>= fun a ->
|
2016-09-08 21:13:10 +04:00
|
|
|
if not (Block_hash.equal a.hash expected.State.Valid_block.hash) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "bad ancestor %s %s" h1 h2 ;
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return_unit in
|
2017-02-24 20:17:53 +04:00
|
|
|
check_ancestor "Genesis" "Genesis" (block s "Genesis") >>= fun () ->
|
|
|
|
check_ancestor "Genesis" "A3" (block s "Genesis") >>= fun () ->
|
|
|
|
check_ancestor "A3" "Genesis" (block s "Genesis") >>= fun () ->
|
|
|
|
check_ancestor "A1" "A1" (block s "A1") >>= fun () ->
|
|
|
|
check_ancestor "A1" "A3" (block s "A1") >>= fun () ->
|
|
|
|
check_ancestor "A3" "A1" (block s "A1") >>= fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
check_ancestor "A6" "B6" (block s "A3") >>= fun () ->
|
|
|
|
check_ancestor "B6" "A6" (block s "A3") >>= fun () ->
|
|
|
|
check_ancestor "A4" "B1" (block s "A3") >>= fun () ->
|
|
|
|
check_ancestor "B1" "A4" (block s "A3") >>= fun () ->
|
|
|
|
check_ancestor "A3" "B1" (block s "A3") >>= fun () ->
|
|
|
|
check_ancestor "B1" "A3" (block s "A3") >>= fun () ->
|
|
|
|
check_ancestor "A2" "B1" (block s "A2") >>= fun () ->
|
|
|
|
check_ancestor "B1" "A2" (block s "A2") >>= fun () ->
|
|
|
|
check_ancestor "C4" "B8" (block s "B7") >>= fun () ->
|
|
|
|
check_ancestor "B8" "C4" (block s "B7") >>= fun () ->
|
|
|
|
check_ancestor "C4" "A8" (block s "A3") >>= fun () ->
|
|
|
|
check_ancestor "A8" "C4" (block s "A3") >>= fun () ->
|
|
|
|
check_valid_ancestor "A6" "B6" (vblock s "A3") >>= fun () ->
|
|
|
|
check_valid_ancestor "B6" "A6" (vblock s "A3") >>= fun () ->
|
|
|
|
check_valid_ancestor "A4" "B1" (vblock s "A3") >>= fun () ->
|
|
|
|
check_valid_ancestor "B1" "A4" (vblock s "A3") >>= fun () ->
|
|
|
|
check_valid_ancestor "A3" "B1" (vblock s "A3") >>= fun () ->
|
|
|
|
check_valid_ancestor "B1" "A3" (vblock s "A3") >>= fun () ->
|
|
|
|
check_valid_ancestor "A2" "B1" (vblock s "A2") >>= fun () ->
|
|
|
|
check_valid_ancestor "B1" "A2" (vblock s "A2") >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.locator *)
|
|
|
|
|
|
|
|
let test_locator s =
|
|
|
|
let check_locator h1 expected =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Block_header.Helpers.block_locator
|
|
|
|
s.net (List.length expected) (fst @@ block s h1) >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| Error _ ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Cannot compute locator for %s" h1
|
2016-09-08 21:13:10 +04:00
|
|
|
| Ok l ->
|
|
|
|
if List.length l <> List.length expected then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg
|
|
|
|
"Invalid locator length %s (found: %d, expected: %d)"
|
2016-09-08 21:13:10 +04:00
|
|
|
h1 (List.length l) (List.length expected) ;
|
|
|
|
List.iter2
|
|
|
|
(fun h h2 ->
|
|
|
|
if not (Block_hash.equal h (fst @@ block s h2)) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Invalid locator %s (expectd: %s)" h1 h2)
|
2016-09-08 21:13:10 +04:00
|
|
|
l expected;
|
|
|
|
Lwt.return_unit in
|
|
|
|
let check_valid_locator h1 expected =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Helpers.block_locator
|
|
|
|
s.net (List.length expected) (vblock s h1) >>= fun l ->
|
2016-09-08 21:13:10 +04:00
|
|
|
if List.length l <> List.length expected then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg
|
|
|
|
"Invalid locator length %s (found: %d, expected: %d)"
|
2016-09-08 21:13:10 +04:00
|
|
|
h1 (List.length l) (List.length expected) ;
|
|
|
|
List.iter2
|
|
|
|
(fun h h2 ->
|
|
|
|
if not (Block_hash.equal h (fst @@ block s h2)) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Invalid locator %s (expectd: %s)" h1 h2)
|
2016-09-08 21:13:10 +04:00
|
|
|
l expected ;
|
|
|
|
Lwt.return_unit in
|
|
|
|
check_locator "A8" ["A8";"A7";"A6";"A5";"A4";"A3";"A2";"A1"] >>= fun () ->
|
|
|
|
check_locator "B8"
|
|
|
|
["B8";"B7";"B6";"B5";"B4";"B3";"B2";"B1";"A3"] >>= fun () ->
|
|
|
|
check_locator "C8"
|
|
|
|
["C8";"C7";"C6";"C5";"C4";"C3";"C2";"C1";
|
|
|
|
"B7";"B6";"B4";"B2";"A3";"A1"] >>= fun () ->
|
|
|
|
check_locator "C8" ["C8";"C7";"C6";"C5";"C4"] >>= fun () ->
|
|
|
|
check_valid_locator "A8"
|
|
|
|
["A8";"A7";"A6";"A5";"A4";"A3";"A2"] >>= fun () ->
|
|
|
|
check_valid_locator "B8"
|
|
|
|
["B8";"B7";"B6";"B5";"B4";"B3";"B2";"B1";"A3"] >>= fun () ->
|
|
|
|
check_valid_locator "B8" ["B8";"B7";"B6";"B5";"B4"] >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.known_heads *)
|
|
|
|
|
|
|
|
let compare s name heads l =
|
2017-02-24 20:17:53 +04:00
|
|
|
if List.length heads <> List.length l then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg
|
|
|
|
"unexpected known_heads size (%s: %d %d)"
|
2017-02-24 20:17:53 +04:00
|
|
|
name (List.length heads) (List.length l) ;
|
2016-09-08 21:13:10 +04:00
|
|
|
List.iter
|
|
|
|
(fun bname ->
|
|
|
|
let hash = (vblock s bname).hash in
|
2017-02-24 20:17:53 +04:00
|
|
|
if not (List.exists (fun b -> Block_hash.equal hash b.State.Valid_block.hash) heads) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "missing block in known_heads (%s: %s)" name bname)
|
2016-09-08 21:13:10 +04:00
|
|
|
l
|
|
|
|
|
|
|
|
let test_known_heads s =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.known_heads s.net >>= fun heads ->
|
2016-09-08 21:13:10 +04:00
|
|
|
compare s "initial" heads ["A8";"B8"] ;
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.head/set_head *)
|
|
|
|
|
|
|
|
let test_head s =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.head s.net >>= fun head ->
|
2016-09-08 21:13:10 +04:00
|
|
|
if not (Block_hash.equal head.hash genesis_block) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "unexpected head" ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "A6") >>= fun _ ->
|
|
|
|
State.Valid_block.Current.head s.net >>= fun head ->
|
2016-09-08 21:13:10 +04:00
|
|
|
if not (Block_hash.equal head.hash (vblock s "A6").hash) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "unexpected head" ;
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.mem *)
|
|
|
|
|
|
|
|
let test_mem s =
|
|
|
|
let mem s x =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.mem s.net (fst @@ block s x) in
|
2016-09-08 21:13:10 +04:00
|
|
|
let test_mem s x =
|
|
|
|
mem s x >>= function
|
|
|
|
| true -> Lwt.return_unit
|
2016-09-30 13:43:50 +04:00
|
|
|
| false -> Assert.fail_msg "mem %s" x in
|
2016-09-08 21:13:10 +04:00
|
|
|
let test_not_mem s x =
|
|
|
|
mem s x >>= function
|
|
|
|
| false -> Lwt.return_unit
|
2016-09-30 13:43:50 +04:00
|
|
|
| true -> Assert.fail_msg "not (mem %s)" x in
|
2016-09-08 21:13:10 +04:00
|
|
|
test_not_mem s "A3" >>= fun () ->
|
|
|
|
test_not_mem s "A6" >>= fun () ->
|
|
|
|
test_not_mem s "A8" >>= fun () ->
|
|
|
|
test_not_mem s "B1" >>= fun () ->
|
|
|
|
test_not_mem s "B6" >>= fun () ->
|
|
|
|
test_not_mem s "B8" >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "A8") >>= fun _ ->
|
2016-09-08 21:13:10 +04:00
|
|
|
test_mem s "A3" >>= fun () ->
|
|
|
|
test_mem s "A6" >>= fun () ->
|
|
|
|
test_mem s "A8" >>= fun () ->
|
|
|
|
test_not_mem s "B1" >>= fun () ->
|
|
|
|
test_not_mem s "B6" >>= fun () ->
|
|
|
|
test_not_mem s "B8" >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "A6") >>= fun _ ->
|
2016-09-08 21:13:10 +04:00
|
|
|
test_mem s "A3" >>= fun () ->
|
|
|
|
test_mem s "A6" >>= fun () ->
|
|
|
|
test_not_mem s "A8" >>= fun () ->
|
|
|
|
test_not_mem s "B1" >>= fun () ->
|
|
|
|
test_not_mem s "B6" >>= fun () ->
|
|
|
|
test_not_mem s "B8" >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "B6") >>= fun _ ->
|
2016-09-08 21:13:10 +04:00
|
|
|
test_mem s "A3" >>= fun () ->
|
|
|
|
test_not_mem s "A4" >>= fun () ->
|
|
|
|
test_not_mem s "A6" >>= fun () ->
|
|
|
|
test_not_mem s "A8" >>= fun () ->
|
|
|
|
test_mem s "B1" >>= fun () ->
|
|
|
|
test_mem s "B6" >>= fun () ->
|
|
|
|
test_not_mem s "B8" >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "B8") >>= fun _ ->
|
2016-09-08 21:13:10 +04:00
|
|
|
test_mem s "A3" >>= fun () ->
|
|
|
|
test_not_mem s "A4" >>= fun () ->
|
|
|
|
test_not_mem s "A6" >>= fun () ->
|
|
|
|
test_not_mem s "A8" >>= fun () ->
|
|
|
|
test_mem s "B1" >>= fun () ->
|
|
|
|
test_mem s "B6" >>= fun () ->
|
|
|
|
test_mem s "B8" >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.new *)
|
|
|
|
|
|
|
|
let test_new s =
|
|
|
|
let test s h expected =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Helpers.block_locator s.net 50 (vblock s h) >>= fun loc ->
|
|
|
|
State.Valid_block.Current.find_new s.net loc (List.length expected) >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| Error _ ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Failed to compute new blocks %s" h
|
2016-09-08 21:13:10 +04:00
|
|
|
| Ok blocks ->
|
|
|
|
if List.length blocks <> List.length expected then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg
|
|
|
|
"Invalid locator length %s (found: %d, expected: %d)"
|
2016-09-08 21:13:10 +04:00
|
|
|
h (List.length blocks) (List.length expected) ;
|
|
|
|
List.iter2
|
|
|
|
(fun h1 h2 ->
|
|
|
|
if not (Block_hash.equal h1 (vblock s h2).hash) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "Invalid locator %s (expected: %s)" h h2)
|
2016-09-08 21:13:10 +04:00
|
|
|
blocks expected ;
|
2016-09-30 13:43:50 +04:00
|
|
|
Lwt.return_unit
|
2016-09-08 21:13:10 +04:00
|
|
|
in
|
|
|
|
test s "A6" [] >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "A8") >>= fun _ ->
|
2016-09-08 21:13:10 +04:00
|
|
|
test s "A6" ["A7";"A8"] >>= fun () ->
|
|
|
|
test s "A6" ["A7"] >>= fun () ->
|
|
|
|
test s "B4" ["A4"] >>= fun () ->
|
|
|
|
test s "B7" ["A4";"A5";"A6";"A7"] >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
(** State.mempool *)
|
|
|
|
|
|
|
|
let compare s name mempool l =
|
2017-02-24 20:17:53 +04:00
|
|
|
let mempool_sz = Operation_hash.Set.cardinal mempool in
|
2016-09-30 13:43:50 +04:00
|
|
|
let l_sz = List.length l in
|
|
|
|
if mempool_sz <> l_sz then
|
|
|
|
Assert.fail
|
|
|
|
(string_of_int mempool_sz)
|
|
|
|
(string_of_int l_sz)
|
|
|
|
"unexpected mempool size (%s)" name ;
|
2016-09-08 21:13:10 +04:00
|
|
|
List.iter
|
|
|
|
(fun oname ->
|
2016-09-30 13:43:50 +04:00
|
|
|
try
|
|
|
|
let oph = fst @@ operation s oname in
|
2017-02-24 20:17:53 +04:00
|
|
|
if not (Operation_hash.Set.mem oph mempool) then
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.fail_msg "missing operation in mempool (%s: %s)" name oname
|
|
|
|
with Not_found ->
|
|
|
|
Assert.fail_msg "Read value not found in mempool (%s: %s)" name oname)
|
2016-09-08 21:13:10 +04:00
|
|
|
l
|
|
|
|
|
|
|
|
let test_mempool s =
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.list_pending s.net >>= fun mempool ->
|
2016-09-08 21:13:10 +04:00
|
|
|
compare s "initial" mempool
|
|
|
|
["PP";
|
|
|
|
"A1" ; "A2" ; "A3" ; "A4" ; "A5" ; "A6" ; "A7" ; "A8" ;
|
|
|
|
"B1" ; "B2" ; "B3" ; "B4" ; "B5" ; "B6" ; "B7" ; "B8" ] ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "A8") >>= fun _ ->
|
|
|
|
State.Operation.list_pending s.net >>= fun mempool ->
|
2016-09-08 21:13:10 +04:00
|
|
|
compare s "A8" mempool
|
|
|
|
["PP"; "B1" ; "B2" ; "B3" ; "B4" ; "B5" ; "B6" ; "B7" ; "B8" ] ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "A6") >>= fun _ ->
|
|
|
|
State.Operation.list_pending s.net >>= fun mempool ->
|
2016-09-08 21:13:10 +04:00
|
|
|
compare s "A6" mempool
|
|
|
|
["PP";
|
|
|
|
"A7" ; "A8" ;
|
|
|
|
"B1" ; "B2" ; "B3" ; "B4" ; "B5" ; "B6" ; "B7" ; "B8" ] ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Valid_block.Current.set_head s.net (vblock s "B6") >>= fun _ ->
|
|
|
|
State.Operation.list_pending s.net >>= fun mempool ->
|
2016-09-08 21:13:10 +04:00
|
|
|
compare s "B6" mempool
|
|
|
|
["PP";
|
|
|
|
"A4" ; "A5" ; "A6" ; "A7" ; "A8" ;
|
|
|
|
"B7" ; "B8" ] ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.mark_invalid s.net (fst @@ operation s "PP") [] >>= fun rm_status ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.is_true ~msg:__LOC__ rm_status ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.mark_invalid s.net (fst @@ operation s "PP") [] >>= fun rm_status ->
|
2016-09-30 13:43:50 +04:00
|
|
|
Assert.is_false ~msg:__LOC__ rm_status ;
|
2017-02-24 20:17:53 +04:00
|
|
|
State.Operation.list_pending s.net >>= fun mempool ->
|
2016-09-08 21:13:10 +04:00
|
|
|
compare s "B6.remove" mempool
|
|
|
|
["A4" ; "A5" ; "A6" ; "A7" ; "A8" ;
|
|
|
|
"B7" ; "B8" ] ;
|
2017-02-24 20:17:53 +04:00
|
|
|
return ()
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
(****************************************************************************)
|
|
|
|
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
let tests : (string * (state -> unit tzresult Lwt.t)) list = [
|
2016-09-08 21:13:10 +04:00
|
|
|
"init", test_init ;
|
|
|
|
"read_operation", test_read_operation;
|
|
|
|
"read_block", test_read_block ;
|
|
|
|
"path", test_path ;
|
|
|
|
"valid_path", test_valid_path ;
|
|
|
|
"ancestor", test_ancestor ;
|
|
|
|
"locator", test_locator ;
|
|
|
|
"known_heads", test_known_heads ;
|
|
|
|
"head", test_head ;
|
|
|
|
"mem", test_mem ;
|
|
|
|
"new", test_new ;
|
|
|
|
"mempool", test_mempool;
|
|
|
|
]
|
|
|
|
|
2016-09-30 13:43:50 +04:00
|
|
|
let () =
|
2016-09-08 21:13:10 +04:00
|
|
|
Test.run "state." (List.map (fun (s, f) -> s, wrap_state_init f) tests)
|