Commit 5a1cae6b authored by Çagdas's avatar Çagdas

Support for amendment

local: 112e9f5cb5f611470a5411003e9599dd9aa60a08
parent 2e195410
...@@ -18,12 +18,12 @@ for the latest sources, issues and contributions: ...@@ -18,12 +18,12 @@ for the latest sources, issues and contributions:
## Copyright and license ## Copyright and license
Copyright OCamlPro 2017-2018. This code is licensed under the terms Copyright OCamlPro 2017-2019. This code is licensed under the terms
of the GNU Public License version 3 (GPL v3). of the GNU Public License version 3 (GPL v3).
## Building ## Building
You need OCaml 4.06.1. You need OCaml 4.07.1.
Update submodules: Update submodules:
...@@ -65,40 +65,34 @@ opam install ...@@ -65,40 +65,34 @@ opam install
``` ```
opam install\ opam install\
camlp4\ base64.2.3.0 \
re.1.7.3\ camlp4 \
ocplib-json-typed\ cohttp-lwt \
ocurl\ cohttp-lwt-unix \
js_of_ocaml\ csv-lwt \
js_of_ocaml-ppx\ ezjsonm \
js_of_ocaml-camlp4\ geoip \
js_of_ocaml-tyxml\ js_of_ocaml \
js_of_ocaml-lwt\ js_of_ocaml-lwt \
omd\ js_of_ocaml-ppx \
cohttp-lwt\ js_of_ocaml-tyxml \
cohttp-lwt-unix\
base64\
ezjsonm\
ocplib-endian\
geoip\
ocp-build\
nocrypto\
sodium\
lru\
alcotest\
calendar \
lwt_log \ lwt_log \
csv-lwt nocrypto \
``` ocamlfind \
ocplib-endian \
You will also need some development versions: ocurl \
``` omd \
opam pin --dev ocplib-json-typed sodium \
opam install ocplib-json-typed zarith \
ocp-build \
ocplib-json-typed \
re \
calendar \
alcotest
``` ```
One last dependency is pgocaml. One last dependency is pgocaml.
The OPAM version is not compatible with tz-scan, also you should install from The OPAM version is not compatible with tzscan, also you should install from
the sources: the sources:
https://github.com/darioteixeira/pgocaml https://github.com/darioteixeira/pgocaml
``` ```
...@@ -141,6 +135,7 @@ WITH_VERSION=true ...@@ -141,6 +135,7 @@ WITH_VERSION=true
API_HOST:=localhost API_HOST:=localhost
API_PORT:=8080 API_PORT:=8080
NEED_PARSEXP=true NEED_PARSEXP=true
BASE64_3:=false
``` ```
The options are: The options are:
...@@ -151,6 +146,7 @@ The options are: ...@@ -151,6 +146,7 @@ The options are:
* WITH_VERSION: set to false to avoid recompiling everything everytime * WITH_VERSION: set to false to avoid recompiling everything everytime
* API_HOST & API_PORT: if you want to use localhost instead of api.tzscan.io * API_HOST & API_PORT: if you want to use localhost instead of api.tzscan.io
* NEED_PARSEXP: if you use sexplib (>= v0.11), then set it to true * NEED_PARSEXP: if you use sexplib (>= v0.11), then set it to true
* BASE64_3: if you use base64 (v>=3.0.0), then set it to true
### Building ### Building
...@@ -237,7 +233,7 @@ Create a file `config.json` containing : ...@@ -237,7 +233,7 @@ Create a file `config.json` containing :
Start the crawler: Start the crawler:
``` ```
./_tzscan-crawler config.json ./tzscan-crawler config.json
``` ```
It should immediately connect to the Tezos node, and rewind the chain It should immediately connect to the Tezos node, and rewind the chain
......
(* Uses JS library blockies https://github.com/ethereum/blockies *) (* Uses JS library blockies https://github.com/ethereum/blockies *)
open Js_of_ocaml
open Js_utils open Js_utils
let alphabet = let alphabet =
......
Subproject commit 3e037b801f865221a9fa534b9a7cffe8d3a5b72b Subproject commit 9e73dfdd56846fc62bb3cd002d2b4c63cf1daae3
Subproject commit f9f144a10744f45c47c064aed7cb1cf87a322521 Subproject commit 1e4995e5051acece10fb41ab1f04ee769e7641b6
Subproject commit 428b9b4ac47a79810b65c4aef961d45e6688d13a Subproject commit acfb41f711cbda67680b84d0f8292e2a1849c711
Subproject commit f9a94efce90f4a933ac0ebf5c6c435f322256394 Subproject commit 60afbdae1226b6f2120a1fff73c8264d6a9f5ef9
...@@ -36,6 +36,7 @@ struct ...@@ -36,6 +36,7 @@ struct
|> register S.accounts H.accounts |> register S.accounts H.accounts
|> register S.nb_accounts H.nb_accounts |> register S.nb_accounts H.nb_accounts
|> register S.account_bonds_rewards H.bonds_rewards |> register S.account_bonds_rewards H.bonds_rewards
|> register S.extra_bonds_rewards H.extra_bonds_rewards
|> register S.rolls_history H.rolls_history |> register S.rolls_history H.rolls_history
|> register S.account_status H.account_status |> register S.account_status H.account_status
(* Operation services *) (* Operation services *)
...@@ -46,6 +47,10 @@ struct ...@@ -46,6 +47,10 @@ struct
|> register S.bakings H.bakings |> register S.bakings H.bakings
|> register S.nb_bakings_endorsement H.nb_bakings_endorsement |> register S.nb_bakings_endorsement H.nb_bakings_endorsement
|> register S.bakings_endorsement H.bakings_endorsement |> register S.bakings_endorsement H.bakings_endorsement
|> register S.nb_cycle_bakings H.nb_cycle_bakings
|> register S.cycle_bakings H.cycle_bakings
|> register S.nb_cycle_endorsements H.nb_cycle_endorsements
|> register S.cycle_endorsements H.cycle_endorsements
|> register S.nb_bakings_history H.nb_bakings_history |> register S.nb_bakings_history H.nb_bakings_history
|> register S.bakings_history H.bakings_history |> register S.bakings_history H.bakings_history
|> register S.nb_endorsements_history H.nb_endorsements_history |> register S.nb_endorsements_history H.nb_endorsements_history
...@@ -111,9 +116,23 @@ struct ...@@ -111,9 +116,23 @@ struct
|> register S.rewards_split_fast H.rewards_split_fast |> register S.rewards_split_fast H.rewards_split_fast
|> register S.nb_cycle_delegator_rewards H.nb_cycle_delegator_rewards |> register S.nb_cycle_delegator_rewards H.nb_cycle_delegator_rewards
|> register S.delegator_rewards H.delegator_rewards |> register S.delegator_rewards H.delegator_rewards
|> register S.delegator_rewards_with_details H.delegator_rewards_with_details
|> register S.h24_stats H.h24_stats |> register S.h24_stats H.h24_stats
|> register S.nb_protocol H.nb_protocol |> register S.nb_protocol H.nb_protocol
|> register S.protocols H.protocols |> register S.protocols H.protocols
|> register S.voting_period_info H.voting_period_info
|> register S.nb_proposals H.nb_proposals
|> register S.proposals H.proposals
|> register S.testing_proposal H.testing_proposal
|> register S.ballots H.ballots
|> register S.votes_account H.votes_account
|> register S.vote_graphs_account H.vote_graphs_account
|> register S.nb_proposal_votes H.nb_proposal_votes
|> register S.proposal_votes H.proposal_votes
|> register S.total_proposal_votes H.total_proposal_votes
|> register S.nb_ballot_votes H.nb_ballot_votes
|> register S.ballot_votes H.ballot_votes
|> register S.total_voters H.total_voters
|> register S.transaction_account_csv H.transaction_account_csv |> register S.transaction_account_csv H.transaction_account_csv
|> register S.market_prices H.market_prices |> register S.market_prices H.market_prices
|> register S.api_server_info H.api_server_info |> register S.api_server_info H.api_server_info
...@@ -128,15 +147,11 @@ struct ...@@ -128,15 +147,11 @@ struct
|> register S.balance_ranking H.balance_ranking |> register S.balance_ranking H.balance_ranking
|> register S.last_baking_and_endorsement H.last_baking_and_endorsement |> register S.last_baking_and_endorsement H.last_baking_and_endorsement
|> register S.next_baking_and_endorsement H.next_baking_and_endorsement |> register S.next_baking_and_endorsement H.next_baking_and_endorsement
|> register S.blocks_with_pred_fitness H.blocks_with_pred_fitness
|> register S.heads_with_pred_fitness H.heads_with_pred_fitness
(* not used in website *) (* not used in website *)
|> register S.roll_number H.roll_number |> register S.roll_number H.roll_number
|> register S.deleguees_count H.deleguees_count
|> register S.deleguees H.deleguees
|> register S.deleguees_count_by_cycle_count H.deleguees_count_by_cycle_count
|> register S.deleguees_count_by_cycle H.deleguees_count_by_cycle
|> register S.all_deleguees_count_by_cycle_count H.all_deleguees_count_by_cycle_count
|> register S.all_deleguees_count_by_cycle H.all_deleguees_count_by_cycle
|> register S.total_bakings H.total_bakings |> register S.total_bakings H.total_bakings
|> register S.total_endorsements H.total_endorsements |> register S.total_endorsements H.total_endorsements
|> register S.cycle_baker_rights H.cycle_baker_rights |> register S.cycle_baker_rights H.cycle_baker_rights
...@@ -153,6 +168,7 @@ end ...@@ -153,6 +168,7 @@ end
module V1 = MakeRegisterer(Service.V1)(Handler.V1) module V1 = MakeRegisterer(Service.V1)(Handler.V1)
module V2 = MakeRegisterer(Service.V2)(Handler.V1) module V2 = MakeRegisterer(Service.V2)(Handler.V1)
module V3 = MakeRegisterer(Service.V3)(Handler.V1)
let services = let services =
EzAPIServer.empty |> V1.register |> V2.register EzAPIServer.empty |> V1.register |> V2.register |> V3.register
...@@ -38,12 +38,15 @@ OCaml.library("tzscan-api-lib", ocaml+ ...@@ -38,12 +38,15 @@ OCaml.library("tzscan-api-lib", ocaml+
]; ];
requires = [ requires = [
"database-reader-lib"; "database-reader-lib";
"database-writer-lib";
"data-types-lib"; "data-types-lib";
"tzscan-config"; "tzscan-config";
"ez-api-cohttp"; "ez-api-cohttp";
"ez-api-server"; "ez-api-server";
"ez-api-curl";
"tezos-explorer-services"; "tezos-explorer-services";
"csv-lwt"; "csv-lwt";
"ez-recaptcha";
]; ];
}); });
...@@ -56,3 +59,14 @@ OCaml.program("tzscan-api-server", ocaml+ ...@@ -56,3 +59,14 @@ OCaml.program("tzscan-api-server", ocaml+
"tzscan-api-lib"; "tzscan-api-lib";
]; ];
}); });
OCaml.program("tzscan-openapi", ocaml+
{
files = [
"openapi_specs.ml";
];
requires = [
"tezos-explorer-services";
"ez-api-server";
];
});
\ No newline at end of file
This diff is collapsed.
(************************************************************************)
(* TzScan *)
(* *)
(* Copyright 2017-2018 OCamlPro *)
(* *)
(* This file is distributed under the terms of the GNU General Public *)
(* License as published by the Free Software Foundation; either *)
(* version 3 of the License, or (at your option) any later version. *)
(* *)
(* TzScan is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)
(* GNU General Public License for more details. *)
(* *)
(************************************************************************)
let str_opt s = Arg.String (fun x -> s := Some x)
let () =
let output_file = ref "tzscan_openapi.json" in
let descr, version, title, terms, contact, license, servers =
ref None, ref None, ref None, ref None, ref None, ref None, ref None in
let speclist =
[ "-o", Arg.String (fun s -> output_file := s), "Optional name (path) of output file";
"--descr", str_opt descr, "Optional API description";
"--version", str_opt version, "Optional API version";
"--title", str_opt title, "Optional API title";
"--terms", str_opt terms, "Optional API terms";
"--contact", str_opt contact, "Optional API contact";
"--license", Arg.Tuple [
Arg.String (fun s -> license := Some (s,""));
Arg.String (fun s -> match !license with
| None -> license := None
| Some (a, _) -> license := Some (a, s))], "Optional API license";
"--servers", Arg.Tuple [
Arg.String (fun s ->
let before = match !servers with
| None -> []
| Some l -> l in
servers := Some ((s,"") :: before));
Arg.String (fun s -> match !servers with
| Some ((a, _) :: t) -> servers := Some ((a, s) :: t)
| _ -> servers := None)], "Optional API license"
] in
let usage_msg = "Create a swagger json file with the services of the API" in
Arg.parse speclist (fun _ -> ()) usage_msg;
let sections = Service.V3.sections in
let str = EzSwagger.to_string
?descr:!descr ?version:!version ?title:!title ?terms:!terms ?license:!license
?servers:!servers ~docs:Service_doc.doc sections in
let oc = open_out !output_file in
output_string oc str;
close_out oc
...@@ -29,8 +29,10 @@ let root = ref None ...@@ -29,8 +29,10 @@ let root = ref None
let default = ref (Some "index.html") let default = ref (Some "index.html")
let node_config = ref None let node_config = ref None
let api_config = ref None let api_config = ref None
let alias_latency = ref 300. let alias_latency = ref 300.
let csv_lifespan = ref (24. *. 3600.)
(* sofar fixed at one day, need to change handler to put it variable *)
let local_services_file = ref None
(* Command-line arguments *) (* Command-line arguments *)
let speclist = [ let speclist = [
...@@ -51,7 +53,77 @@ let speclist = [ ...@@ -51,7 +53,77 @@ let speclist = [
" No default for file-server (return 404)"; " No default for file-server (return 404)";
"--time-alias", Arg.Set_float alias_latency, "--time-alias", Arg.Set_float alias_latency,
"Latency for alias table update"; "Latency for alias table update";
] "--verbose-db", Arg.Set Reader.verbose_mode,
" Verbosity mode for DB requests";
"--local-services", Arg.String (fun s -> local_services_file := Some s),
"Choose a local services.json instead of the one on the web server";
"--csv-lifespan", Arg.Float (fun f -> csv_lifespan := f *. 3600.),
"Lifespan of csv"
]
let services_encoding = ref None
let encoding_hook encoding =
services_encoding := Some encoding
let update_aliases () =
Lwt.return @@
match !services_encoding with
| None -> Printf.printf "services encoding not loaded\n%!"
| Some services_encoding ->
match !local_services_file with
| None ->
begin
match Config.get_services_filename () with
| None ->
Printf.eprintf "No services, no aliases to update.\n%!" ;
| Some url ->
try
EzCurl.get "" (EzAPI.TYPES.URL url)
~error:(fun i s ->
let msg = match s with None -> "" | Some s -> s in
Printf.eprintf "Downloading services from %S... \
[ FAIL ] [ %d ] [ %S ]\n%!" url i msg)
(fun content ->
Printf.eprintf "Downloading services from %S... [ OK ]\n%!" url ;
let json = Ezjsonm.from_string content in
Alias.change_aliases_from_json services_encoding json)
with Curl.CurlException (_code, i, s) ->
Printf.eprintf "[Service request] [%d] %s Curl exception: %s\n%!" i url s
end
| Some filename ->
try
Printf.eprintf "Reading services from %S\n%!" filename ;
let ic = open_in filename in
begin
try
let json = Ezjsonm.from_channel ic in
Alias.change_aliases_from_json services_encoding json
with exn ->
Printf.eprintf "Fatal error while destructing %S:\n %s\n%!"
filename (Printexc.to_string exn)
end;
close_in ic
with exn ->
Printf.eprintf "Fatal error while reading %S:\n %s\n%!"
filename (Printexc.to_string exn)
let clear_csv () =
match Config.get_csv_dir () with
| Some csv_dir when (String.length csv_dir) > 10 ->
begin
try
let a = Sys.readdir csv_dir in
Printf.eprintf "Cleaning CSV directory at %S\n%!" csv_dir ;
Array.iter (fun s ->
Sys.remove @@ Printf.sprintf "%s%s" csv_dir s) a
with Sys_error _ ->
Printf.eprintf "Directory to store csv files not found at %S.\
\nMaybe you should try `mkdir %s` first."
csv_dir csv_dir ;
exit 1
end
| _ -> ()
(* Main *) (* Main *)
let server services = let server services =
...@@ -81,21 +153,19 @@ let server services = ...@@ -81,21 +153,19 @@ let server services =
Lwt_main.run ( Lwt_main.run (
Stats.init () >>= fun () -> Stats.init () >>= fun () ->
Printf.eprintf "Starting servers on ports [%s]\n%!" Printf.eprintf "Starting servers on ports [%s]\n%!"
(String.concat "," (String.concat ","
(List.map (fun (port,_) -> (List.map (fun (port,_) ->
string_of_int port) servers)); string_of_int port) servers));
let update_table () =
Dbr.all_aliases () >>= fun l ->
Alias.reset ();
List.iter (fun (hash, alias) -> Alias.change_alias hash alias) l;
Lwt.return_unit
in
let rec update_loop () = let rec update_loop () =
Printf.printf "Updating alias table [in progress]...\n%!"; Printf.printf "Updating alias table [in progress]...\n%!";
update_table () >>= fun () -> update_aliases () >>= fun () ->
Printf.printf "Updating alias table [OK]...\n%!"; Printf.printf "Updating alias table [done]...\n%!";
Lwt_unix.sleep !alias_latency >>= fun () -> Lwt_unix.sleep !alias_latency >>= fun () ->
update_loop () in update_loop () in
let rec csv_gc () =
clear_csv ();
Lwt_unix.sleep !csv_lifespan >>= fun () ->
csv_gc () in
Lwt_list.iter_p (fun x -> x) Lwt_list.iter_p (fun x -> x)
[EzAPIServer.server servers; update_loop ()] [EzAPIServer.server servers; update_loop (); csv_gc ()]
) )
...@@ -15,3 +15,5 @@ ...@@ -15,3 +15,5 @@
(************************************************************************) (************************************************************************)
val server : EzAPI.request EzAPIServer.directory -> unit val server : EzAPI.request EzAPIServer.directory -> unit
val encoding_hook : Data_types.service list Json_encoding.encoding -> unit
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -31,34 +31,42 @@ let address_encoding = ...@@ -31,34 +31,42 @@ let address_encoding =
let all_addresses = ref [] let all_addresses = ref []
let api_addresses = ref [||] let api_addresses = ref [||]
let services_filename = ref None
type config = let secret_key = ref None
{ let csv_dir = ref None
name : string ;
crawler : address list ; type config = {
api : address list ; name : string ;
data_path : string option ; crawler : address list ;
} api : address list ;
services_filename : string option ;
data_path : string option ;
recaptcha_secret_key : string option;
csv_dir : string option
}
let config_encoding = let config_encoding =
conv conv
(fun (fun { name ; crawler ; api ; services_filename ; data_path ;
{ name ; crawler ; api ; data_path } recaptcha_secret_key ; csv_dir }
-> ( name , crawler , api , data_path , None , None ) -> ( name , crawler , api , services_filename, data_path , None , None ,
) recaptcha_secret_key, csv_dir ))
(fun (fun ( name , crawler , api , services_filename , data_path,
( name , crawler , api , data_path, _max_default_blocks , _max_default_operations, recaptcha_secret_key ,
_max_default_blocks , _max_default_operations ) csv_dir )
-> { name ; crawler ; api ; data_path } -> { name ; crawler ; api ; services_filename ; data_path ;
recaptcha_secret_key ; csv_dir }
) )
( obj6 ( obj9
(req "name" string) (req "name" string)
(req "crawler" (list address_encoding)) (req "crawler" (list address_encoding))
(req "api" (list address_encoding)) (req "api" (list address_encoding))
(opt "services" string)
(opt "data" string) (opt "data" string)
(opt "max_default_blocks" int) (opt "max_default_blocks" int)
(opt "max_default_operations" int) (opt "max_default_operations" int)
) (opt "recaptcha_secret_key" string)
(opt "csv_dir" string))
let configs_encoding = list config_encoding let configs_encoding = list config_encoding
...@@ -68,7 +76,10 @@ let configs_example = [ ...@@ -68,7 +76,10 @@ let configs_example = [
api = [ api = [
{ url = "http://another-host"; port = 18732 }; { url = "http://another-host"; port = 18732 };
]; ];
services_filename = None ;
data_path = None; data_path = None;
recaptcha_secret_key = None;
csv_dir = None
} }
] ]
...@@ -134,7 +145,10 @@ let load_config_api file = ...@@ -134,7 +145,10 @@ let load_config_api file =
| [] -> crawler_addresses | [] -> crawler_addresses
| _ -> addresses | _ -> addresses
in in
services_filename := c.services_filename ;
api_addresses := Array.of_list addresses; api_addresses := Array.of_list addresses;
secret_key := c.recaptcha_secret_key;
csv_dir := c.csv_dir;
begin begin
match !api_addresses with match !api_addresses with
| [||] -> error "No node addresses for balance queries" | [||] -> error "No node addresses for balance queries"
...@@ -162,10 +176,14 @@ let get_config_crawler ~crawler file = ...@@ -162,10 +176,14 @@ let get_config_crawler ~crawler file =
} }
let get_addresses () = !all_addresses let get_addresses () = !all_addresses
let get_services_filename () = !services_filename
let get_api_address () = let get_api_address () =
let api_addresses = !api_addresses in let api_addresses = !api_addresses in
snd api_addresses.(Random.int (Array.length api_addresses)) snd api_addresses.(Random.int (Array.length api_addresses))
let get_secret_key () = !secret_key
let get_csv_dir () = !csv_dir
(* (*
let get_address_pref ?fpref () = let get_address_pref ?fpref () =
let rec aux = function let rec aux = function
......
...@@ -17,7 +17,10 @@ ...@@ -17,7 +17,10 @@
val load_config_api : string option -> unit val load_config_api : string option -> unit
val get_addresses : unit -> (string * string) list val get_addresses : unit -> (string * string) list
val get_api_address : unit -> string val get_api_address : unit -> string
val get_services_filename : unit -> string option
val get_config_crawler : val get_config_crawler :
crawler:string -> string -> Data_types.config crawler:string -> string -> Data_types.config
val load_json_config : 'a Json_encoding.encoding -> string -> 'a val load_json_config : 'a Json_encoding.encoding -> string -> 'a
val error : string -> 'a val error : string -> 'a
val get_secret_key : unit -> string option
val get_csv_dir : unit -> string option
...@@ -33,7 +33,7 @@ let choose_fields header_all fields_all header = ...@@ -33,7 +33,7 @@ let choose_fields header_all fields_all header =
let transaction_header = let transaction_header =
["transaction"; "block"; "network"; "source"; "destination"; "amount"; "fee"; ["transaction"; "block"; "network"; "source"; "destination"; "amount"; "fee";
"parameters"; "failed"; "internal"; "burned tez"; "counter"; "gas limit"; "date"; "parameters"; "failed"; "internal"; "burned tez"; "counter"; "gas limit";
"storage limit"] "storage limit"]
let transaction header o = let transaction header o =
...@@ -49,6 +49,7 @@ let transaction header o = ...@@ -49,6 +49,7 @@ let transaction header o =
tr.tr_dst.tz; tr.tr_dst.tz;
Int64.to_string tr.tr_amount; Int64.to_string tr.tr_amount;
Int64.to_string tr.tr_fee; Int64.to_string tr.tr_fee;
tr.tr_timestamp;
Misc.unopt "" tr.tr_parameters; Misc.unopt "" tr.tr_parameters;
string_of_bool tr.tr_failed; string_of_bool tr.tr_failed;
string_of_bool tr.tr_internal; string_of_bool tr.tr_internal;
......
...@@ -23,7 +23,7 @@ type account_name = { tz : account_hash; alias : string option } ...@@ -23,7 +23,7 @@ type account_name = { tz : account_hash; alias : string option }
type config = type config =
{ nodes : url list ; data_path : string option } { nodes : url list ; data_path : string option }
type nonces = int * (operation_hash * (int list)) list type nonces = int * (operation_hash option * int * block_hash) list
type block = { type block = {
hash : block_hash ; hash : block_hash ;
...@@ -142,6 +142,8 @@ and origination = { ...@@ -142,6 +142,8 @@ and origination = {
or_failed : bool ; or_failed : bool ;
or_internal : bool ; or_internal : bool ;
or_burn : int64 ; or_burn : int64 ;
or_op_level : int ;
or_timestamp : string
} }
and delegation = { and delegation = {
...@@ -153,6 +155,8 @@ and delegation = { ...@@ -153,6 +155,8 @@ and delegation = {
del_storage_limit : Z.t ; del_storage_limit : Z.t ;
del_failed : bool ; del_failed : bool ;
del_internal : bool ; del_internal : bool ;
del_op_level : int ;
del_timestamp : string
} }
and reveal = { and reveal = {
...@@ -164,11 +168,16 @@ and reveal = { ...@@ -164,11 +168,16 @@ and reveal = {