• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MinaProtocol / mina / 80

14 Apr 2025 10:52PM UTC coverage: 60.82% (+24.9%) from 35.871%
80

push

buildkite

web-flow
Merge pull request #16871 from MinaProtocol/georgeee/last-before-zkapp-stable-hash-removal

Some changes required for hash removal from Zkapp_command.Stable

2 of 3 new or added lines in 2 files covered. (66.67%)

1322 existing lines in 28 files now uncovered.

49978 of 82173 relevant lines covered (60.82%)

475582.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.75
/src/app/cli/src/init/itn.ml
1
(* itn.ml -- code for incentivized testnet *)
2

6✔
3
open Core
4
open Async
5
open Signature_lib
6
open Mina_base
7
open Mina_transaction
8

9
let create_accounts ~(genesis_constants : Genesis_constants.t)
10
    ~(constraint_constants : Genesis_constants.Constraint_constants.t) port
11
    (privkey_path, key_prefix, num_accounts, fee, amount) =
12
  let keys_per_zkapp = 8 in
×
13
  let zkapps_per_block = 10 in
14
  let pk_check_wait = Time.Span.of_sec 10. in
15
  let pk_check_timeout = Time.Span.of_min 30. in
×
16
  let min_fee =
×
17
    Currency.Fee.to_nanomina_int genesis_constants.minimum_user_command_fee
18
  in
19
  let account_creation_fee_int =
×
20
    Currency.Fee.to_nanomina_int constraint_constants.account_creation_fee
21
  in
22
  if fee < min_fee then (
×
23
    Format.eprintf "Minimum fee is %d@." min_fee ;
24
    Core.exit 1 ) ;
×
25
  if not @@ Option.is_some @@ Sys.getenv Secrets.Keypair.env then (
×
26
    Format.eprintf "Please set environment variable %s@." Secrets.Keypair.env ;
27
    Core.exit 1 ) ;
×
28
  let%bind fee_payer_keypair =
29
    Secrets.Keypair.Terminal_stdin.read_exn ~which:"Mina fee payer keypair"
×
30
      privkey_path
31
  in
32
  let fee_payer_account_id =
×
33
    let pk =
34
      fee_payer_keypair.public_key |> Signature_lib.Public_key.compress
35
    in
36
    Account_id.create pk Token_id.default
×
37
  in
38
  let%bind fee_payer_balance =
39
    match%bind
40
      Daemon_rpcs.Client.dispatch Daemon_rpcs.Get_balance.rpc
×
41
        fee_payer_account_id port
42
    with
43
    | Ok (Ok (Some balance)) ->
×
44
        Deferred.return balance
45
    | Ok (Ok None) ->
×
46
        Format.eprintf "Could not get fee payer balance" ;
47
        exit 1
×
48
    | Ok (Error err) ->
×
49
        Format.eprintf "Error getting fee payer balance: %s@."
50
          (Error.to_string_hum err) ;
×
51
        exit 1
×
52
    | Error err ->
×
53
        Format.eprintf "Failed to get fee payer balance, error: %s@."
54
          (Error.to_string_hum err) ;
×
55
        exit 1
×
56
  in
57
  let fee_payer_balance_as_amount =
×
58
    Currency.Balance.to_amount fee_payer_balance
59
  in
60
  let%bind fee_payer_initial_nonce =
61
    (* inferred nonce considers txns in pool, in addition to ledger *)
62
    match%map
63
      Daemon_rpcs.Client.dispatch Daemon_rpcs.Get_inferred_nonce.rpc
×
64
        fee_payer_account_id port
65
    with
66
    | Ok (Ok (Some nonce)) ->
×
67
        Account.Nonce.of_uint32 nonce
68
    | Ok (Ok None) ->
×
69
        Format.eprintf "No account found for fee payer@." ;
70
        Core.exit 1
×
71
    | Ok (Error err) | Error err ->
×
72
        Format.eprintf "Failed to get fee payer nonce: %s@."
73
          (Error.to_string_hum err) ;
×
74
        Core.exit 1
×
75
  in
76
  Format.printf "Fee payer public key: %s, initial nonce = %d@."
×
77
    ( Account_id.public_key fee_payer_account_id
×
78
    |> Public_key.Compressed.to_base58_check )
×
79
    (Account.Nonce.to_int fee_payer_initial_nonce) ;
×
80
  let fee_payer_current_nonce = ref fee_payer_initial_nonce in
×
81
  let keypairs =
82
    List.init num_accounts ~f:(fun _n -> Signature_lib.Keypair.create ())
×
83
  in
84
  let%bind () =
85
    Deferred.List.iteri keypairs ~f:(fun i kp ->
×
86
        let privkey_path = sprintf "%s-%d" key_prefix i in
×
87
        let pk =
×
88
          Signature_lib.Public_key.compress kp.public_key
×
89
          |> Signature_lib.Public_key.Compressed.to_base58_check
90
        in
91
        Format.printf "Writing key file %s for public key %s@." privkey_path pk ;
×
92
        Secrets.Keypair.Terminal_stdin.write_exn kp ~privkey_path )
×
93
  in
94
  let keypair_chunks = List.chunks_of keypairs ~length:keys_per_zkapp in
×
95
  let num_chunks = List.length keypair_chunks in
×
96
  (* amount + fees must not be more than fee payer balance *)
97
  let amount_and_fees =
×
98
    let total_fees = num_chunks * fee in
99
    Currency.Amount.of_nanomina_int_exn (amount + total_fees)
×
100
  in
101
  if Currency.Amount.( > ) amount_and_fees fee_payer_balance_as_amount then (
×
102
    Format.eprintf
103
      !"Amount plus fees (%{sexp: Currency.Amount.t}) is greater than fee \
×
104
        payer balance (%{sexp: Currency.Amount.t})@."
105
      amount_and_fees fee_payer_balance_as_amount ;
106
    Core.exit 1 ) ;
×
107
  let amount_per_key = amount / num_accounts in
×
108
  let chunk_amounts =
109
    Array.init num_chunks ~f:(fun i ->
110
        let chunk_len = List.length (List.nth_exn keypair_chunks i) in
×
111
        chunk_len * amount_per_key )
×
112
  in
113
  let rec top_off_chunks i total =
×
114
    if total < amount then (
×
115
      chunk_amounts.(i) <- chunk_amounts.(i) + 1 ;
116
      top_off_chunks ((i + 1) mod num_chunks) (total + 1) )
×
117
  in
118
  let chunk_total = Array.fold chunk_amounts ~init:0 ~f:( + ) in
119
  top_off_chunks 0 chunk_total ;
×
120
  assert (Array.fold chunk_amounts ~init:0 ~f:( + ) = amount) ;
×
121
  let zkapps =
122
    List.mapi keypair_chunks ~f:(fun i kps ->
123
        let num_updates = List.length kps in
×
124
        let chunk_amount = chunk_amounts.(i) in
×
125
        if Int.is_negative chunk_amount then (
×
126
          Format.eprintf
127
            "Calculated negative amount for chunk of account updates; increase \
128
             amount or lower fee@." ;
129
          Core.exit 1 ) ;
×
130
        let amount_per_update =
×
131
          (chunk_amount / num_updates) - account_creation_fee_int
132
        in
133
        let update_rem = chunk_amount mod num_updates in
134
        let update_amounts =
135
          Array.init num_updates ~f:(fun i ->
136
              if i < update_rem then amount_per_update + 1
×
137
              else amount_per_update )
×
138
        in
139
        assert (
×
140
          Array.fold update_amounts ~init:0 ~f:( + )
×
141
          = chunk_amount - (num_updates * account_creation_fee_int) ) ;
142
        let memo_str = sprintf "ITN account funder, chunk %d" i in
143
        let memo = Signed_command_memo.create_from_string_exn memo_str in
×
144
        let multispec : Transaction_snark.For_tests.Multiple_transfers_spec.t =
×
145
          let fee = Currency.Fee.of_nanomina_int_exn fee in
146
          let sender = (fee_payer_keypair, !fee_payer_current_nonce) in
×
147
          let fee_payer = None in
148
          let receivers =
149
            List.mapi kps ~f:(fun j kp ->
150
                let pk = kp.public_key |> Signature_lib.Public_key.compress in
×
151
                let amount =
×
152
                  update_amounts.(j) |> Currency.Amount.of_nanomina_int_exn
153
                in
154
                (pk, amount) )
×
155
          in
156
          let amount = chunk_amount |> Currency.Amount.of_nanomina_int_exn in
×
157
          let zkapp_account_keypairs = [] in
×
158
          let new_zkapp_account = false in
159
          let snapp_update = Account_update.Update.dummy in
160
          let actions = [] in
161
          let events = [] in
162
          let call_data = Snark_params.Tick.Field.zero in
163
          let preconditions = Some Account_update.Preconditions.accept in
164
          { fee
165
          ; sender
166
          ; fee_payer
167
          ; receivers
168
          ; amount
169
          ; zkapp_account_keypairs
170
          ; memo
171
          ; new_zkapp_account
172
          ; snapp_update
173
          ; actions
174
          ; events
175
          ; call_data
176
          ; preconditions
177
          }
178
        in
179
        fee_payer_current_nonce := Account.Nonce.succ !fee_payer_current_nonce ;
×
180
        Transaction_snark.For_tests.multiple_transfers ~constraint_constants
181
          multispec )
182
  in
183
  (* TODO do not compute hashes and remove Zkapp_command.read_all_proofs_from_disk *)
184
  let zkapps_batches = List.chunks_of zkapps ~length:zkapps_per_block in
×
185
  Deferred.List.iter zkapps_batches ~f:(fun zkapps_batch ->
×
186
      Format.printf "Processing batch of %d zkApps@." (List.length zkapps_batch) ;
×
187
      List.iteri zkapps_batch ~f:(fun i zkapp ->
×
188
          let txn_hash =
×
UNCOV
189
            Transaction_hash.hash_wrapped_zkapp_command zkapp
×
190
            |> Transaction_hash.to_base58_check
191
          in
192
          Format.printf " zkApp %d, transaction hash: %s@." i txn_hash ;
×
193
          Format.printf " Fee payer: %s, nonce: %d@."
×
UNCOV
194
            (Signature_lib.Public_key.Compressed.to_base58_check
×
195
               zkapp.fee_payer.body.public_key )
196
            (Account.Nonce.to_int zkapp.fee_payer.body.nonce) ;
×
197
          Format.printf " Account updates@." ;
×
UNCOV
198
          Zkapp_command.Call_forest.iteri zkapp.account_updates
×
199
            ~f:(fun _i acct_update ->
UNCOV
200
              let pk =
×
201
                Signature_lib.Public_key.Compressed.to_base58_check
202
                  acct_update.body.public_key
203
              in
UNCOV
204
              let balance_change = acct_update.body.balance_change in
×
205
              let sgn =
206
                if Currency.Amount.Signed.is_negative balance_change then "-"
×
UNCOV
207
                else ""
×
208
              in
209
              let balance_change_str =
210
                match
211
                  Currency.Amount.to_yojson
UNCOV
212
                  @@ Currency.Amount.Signed.magnitude balance_change
×
213
                with
UNCOV
214
                | `String s ->
×
215
                    s
UNCOV
216
                | _ ->
×
217
                    failwith "Expected string"
218
              in
219
              Format.printf "  Public key: %s  Balance change: %s%s@." pk sgn
220
                balance_change_str ) ) ;
221
      let%bind res =
UNCOV
222
        Daemon_rpcs.Client.dispatch Daemon_rpcs.Send_zkapp_commands.rpc
×
UNCOV
223
          (List.map ~f:Zkapp_command.read_all_proofs_from_disk zkapps_batch)
×
224
          port
225
      in
UNCOV
226
      ( match res with
×
227
      | Ok res_inner -> (
×
228
          match res_inner with
229
          | Ok zkapps ->
×
230
              Format.printf "Successfully sent %d zkApps to transaction pool@."
×
UNCOV
231
                (List.length zkapps)
×
232
          | Error err ->
×
233
              Format.eprintf "When sending zkApps, got error: %s@."
234
                (Error.to_string_hum err) ;
×
UNCOV
235
              Core.exit 1 )
×
236
      | Error err ->
×
237
          Format.printf "Failed to send zkApps, error: %s@."
UNCOV
238
            (Error.to_string_hum err) ;
×
239
          Core.exit 1 ) ;
×
240
      let batch_pks =
241
        List.map zkapps_batch ~f:(fun zkapp ->
×
242
            let acct_update_pks =
×
UNCOV
243
              List.map (Zkapp_command.Call_forest.to_list zkapp.account_updates)
×
244
                ~f:(fun acct_update -> acct_update.body.public_key)
×
245
            in
UNCOV
246
            zkapp.fee_payer.body.public_key :: acct_update_pks )
×
UNCOV
247
        |> List.concat
×
248
        |> List.dedup_and_sort
249
             ~compare:Signature_lib.Public_key.Compressed.compare
250
      in
UNCOV
251
      let num_batch_pks = List.length batch_pks in
×
252
      Format.eprintf "Number of batch keys: %d@." num_batch_pks ;
×
253
      (* check for presence of all pks *)
254
      let check_for_pks () =
×
UNCOV
255
        Deferred.List.for_all batch_pks ~f:(fun pk ->
×
256
            let account_id = Account_id.create pk Token_id.default in
×
257
            let%map res =
UNCOV
258
              Daemon_rpcs.Client.dispatch Daemon_rpcs.Get_balance.rpc account_id
×
259
                port
260
            in
261
            match res with
×
262
            | Ok (Ok (Some balance)) when Currency.Balance.(balance > zero) ->
×
UNCOV
263
                true
×
UNCOV
264
            | Ok (Ok (Some _)) | Ok (Ok None) | Ok (Error _) | Error _ ->
×
265
                false )
266
      in
267
      let rec check_loop () =
UNCOV
268
        let%bind got_pks = check_for_pks () in
×
269
        if got_pks then (
×
270
          Format.printf "Found all batch public keys in daemon ledger@." ;
UNCOV
271
          Deferred.unit )
×
UNCOV
272
        else (
×
273
          Format.printf
274
            "Did not find all batch public keys in daemon ledger, will retry@." ;
UNCOV
275
          let%bind () = after pk_check_wait in
×
UNCOV
276
          check_loop () )
×
277
      in
278
      Format.printf "Checking daemon ledger for batch public keys ...@." ;
UNCOV
279
      match%bind Async.with_timeout pk_check_timeout (check_loop ()) with
×
280
      | `Result _ ->
×
281
          Deferred.unit
UNCOV
282
      | `Timeout ->
×
283
          Format.eprintf
284
            "Timed out (%s) waiting to find batch public keys in daemon \
285
             ledger@."
UNCOV
286
            (Time.Span.to_string pk_check_timeout) ;
×
UNCOV
287
          exit 1 )
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc