Source file client_proto_main.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
open Protocol
open Protocol_client_context
let protocol =
Protocol_hash.of_b58check_exn
"Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P"
let bake cctxt ?timestamp block command sk =
let timestamp =
match timestamp with
| Some t -> t
| None -> Time.System.(to_protocol (Tezos_base.Time.System.now ()))
in
let protocol_data = {command; signature = Tezos_crypto.Signature.V0.zero} in
Genesis_block_services.Helpers.Preapply.block
cctxt
~block
~timestamp
~protocol_data
[]
>>=? fun (, _) ->
let blk = Data.Command.forge shell_header command in
Shell_services.Chain.chain_id cctxt ~chain:`Main () >>=? fun chain_id ->
Client_keys_v0.append cctxt sk ~watermark:(Block_header chain_id) blk
>>=? fun signed_blk -> Shell_services.Injection.block cctxt signed_blk []
let int32_parameter =
Tezos_clic.parameter (fun _ p ->
match Int32.of_string p with
| i32 ->
if Compare.Int32.(i32 < 0l) then
failwith "Cannot provide a negative int32"
else return i32
| exception _ -> failwith "Cannot read int32")
let file_parameter =
Tezos_clic.parameter (fun _ p ->
if not (Sys.file_exists p) then failwith "File doesn't exist: '%s'" p
else return p)
let fitness_from_uint32 fitness =
let version_number = "\002" in
let int32_to_bytes i =
let b = Bytes.create 4 in
TzEndian.set_int32 b 0 i ;
b
in
let fitness_to_round = Int32.(max 0l (pred fitness)) in
[
Bytes.of_string version_number ;
int32_to_bytes 0l ;
Bytes.empty ;
int32_to_bytes (-1l) ;
int32_to_bytes fitness_to_round ;
]
let timestamp_arg =
Tezos_clic.arg
~long:"timestamp"
~placeholder:"date"
~doc:"Set the timestamp of the block (and initial time of the chain)"
(Tezos_clic.parameter (fun _ t ->
match Time.Protocol.of_notation t with
| None ->
failwith "Could not parse value provided to -timestamp option"
| Some t -> return t))
let test_delay_arg =
Tezos_clic.default_arg
~long:"delay"
~placeholder:"time"
~doc:"Set the life span of the test chain (in seconds)"
~default:(Int64.to_string (Int64.mul 24L 3600L))
(Tezos_clic.parameter (fun _ t ->
match Int64.of_string_opt t with
| None -> failwith "Could not parse value provided to -delay option"
| Some t -> return t))
let proto_param ~name ~desc t =
Tezos_clic.param
~name
~desc
(Tezos_clic.parameter (fun _ str ->
Lwt.return (Protocol_hash.of_b58check str)))
t
let commands () =
let open Tezos_clic in
let args = args1 timestamp_arg in
[
command
~desc:"Activate a protocol"
args
(prefixes ["activate"; "protocol"]
@@ proto_param ~name:"version" ~desc:"Protocol version (b58check)"
@@ prefixes ["with"; "fitness"]
@@ param
~name:"fitness"
~desc:"Hardcoded fitness of the first block (integer)"
int32_parameter
@@ prefixes ["and"; "key"]
@@ Client_keys_v0.Secret_key.source_param
~name:"password"
~desc:"Activator's key"
@@ prefixes ["and"; "parameters"]
@@ param
~name:"parameters"
~desc:"Protocol parameters (as JSON file)"
file_parameter
@@ stop)
(fun timestamp
hash
fitness
sk
param_json_file
(cctxt : Client_context.full) ->
let fitness = fitness_from_uint32 fitness in
Tezos_stdlib_unix.Lwt_utils_unix.Json.read_file param_json_file
>>=? fun json ->
let protocol_parameters =
Data_encoding.Binary.to_bytes_exn Data_encoding.json json
in
bake
cctxt
?timestamp
cctxt#block
(Activate {protocol = hash; fitness; protocol_parameters})
sk
>>=? fun hash ->
cctxt#answer "Injected %a" Block_hash.pp_short hash >>= fun () ->
return_unit);
command
~desc:"Fork a test protocol"
(args2 timestamp_arg test_delay_arg)
(prefixes ["fork"; "test"; "protocol"]
@@ proto_param ~name:"version" ~desc:"Protocol version (b58check)"
@@ prefixes ["with"; "key"]
@@ Client_keys_v0.Secret_key.source_param
~name:"password"
~desc:"Activator's key"
@@ stop)
(fun (timestamp, delay) hash sk cctxt ->
bake
cctxt
?timestamp
cctxt#block
(Activate_testchain {protocol = hash; delay})
sk
>>=? fun hash ->
cctxt#answer "Injected %a" Block_hash.pp_short hash >>= fun () ->
return_unit);
]
let () = Client_commands.register protocol @@ fun _network -> commands ()