add result.ml; polymorphic variant errors + refacto

This commit is contained in:
swrup 2026-03-26 06:23:42 +01:00 committed by Swrup
parent 9fd3b5a3cc
commit 42b0ec1445
36 changed files with 949 additions and 954 deletions

View file

@ -43,30 +43,29 @@ module Arg = struct
in
Arg.Conv.make ~docv:"relative time argument" ~parser ~pp ()
let amount =
Arg.Conv.make ~docv:"amount argument" ~parser:Amount.of_string ~pp:Amount.pp
()
let b32 =
let pp fmt v = Fmt.pf fmt "%s" (B32.encode v) in
Arg.Conv.make ~docv:"Crockford's Base32 encoded argument" ~parser:B32.decode
~pp ()
let amount =
Arg.Conv.make ~docv:"amount argument" ~parser:Amount.of_string ~pp:Amount.pp
()
let eddsa_pub =
let parser s = Eddsa.pub_of_b32 s in
let pp fmt key =
let s = Eddsa.pub_to_b32 key in
Fmt.pf fmt "%s" s
in
Arg.Conv.make ~docv:"eddsa public key argument" ~parser ~pp ()
Arg.Conv.make ~docv:"eddsa public key argument" ~parser:Eddsa.pub_of_b32 ~pp
()
let rsa_pub =
let parser s = Rsa.pub_of_b32 s in
let pp fmt key =
let s = Rsa.pub_to_b32 key in
Fmt.pf fmt "%s" s
in
Arg.Conv.make ~docv:"rsa public key argument" ~parser ~pp ()
Arg.Conv.make ~docv:"rsa public key argument" ~parser:Rsa.pub_of_b32 ~pp ()
end
let master_key =
@ -151,10 +150,8 @@ let compute_denomination_hash_cmd =
Cmd.make (Cmd.info "compute-denomination-hash" ~doc)
@@
let+ rsa_pub = rsa_pub in
rsa_pub
|> Hash.DenominationHash.hash_of_rsa
|> Hash.DenominationHash.to_b32
|> Fmt.pr "%s@.";
let open Hash.DenominationHash in
Fmt.pr "%a@." pp (hash rsa_pub);
Ok ()
let revoke_signkey_cmd =
@ -322,11 +319,11 @@ let drain_cmd =
and+ master_key = master_key
and+ debit_account_section = debit_account_section
and+ credit_payto_uri = credit_payto_uri
and+ wtid = wtid
and+ wtid_octets = wtid
and+ date = date
and+ amount = amount in
drain ~output ~master_key ~debit_account_section ~credit_payto_uri ~wtid ~date
~amount
drain ~output ~master_key ~debit_account_section ~credit_payto_uri
~wtid_octets ~date ~amount
let cli =
let info =

View file

@ -2,6 +2,8 @@ open Syntax
open Time
open Hash
let () = Mirage_crypto_rng_unix.use_default ()
let now_s () =
let ns = Mtime_clock.now_ns () in
Int64.unsigned_div ns 1_000_000_000L
@ -37,7 +39,7 @@ module Future_keys = struct
let rsa_pub =
match denom_pub with DenominationKey.Rsa denom -> denom.rsa_pub
in
let h_denom_pub = DenominationHash.hash_of_rsa rsa_pub in
let h_denom_pub = DenominationHash.hash rsa_pub in
let h_section_name = H64_cstring.hash section_name in
let anchor_time = stamp_start in
let duration_withdraw =
@ -60,7 +62,7 @@ module Future_keys = struct
let* () =
match master_pub = offline_master_public_key with
| false ->
Fmt.error
Fmt.error_msg
"master public key of the future key response does not match ours"
| true -> Ok ()
in
@ -104,7 +106,7 @@ module Future_keys = struct
let rsa_pub =
match denom_pub with DenominationKey.Rsa denom -> denom.rsa_pub
in
let h_denom_pub = DenominationHash.hash_of_rsa rsa_pub in
let h_denom_pub = DenominationHash.hash rsa_pub in
let master_sig =
let open Signatures.DenominationKeyValidity in
let master = Eddsa.pub_of_priv master_key in
@ -149,16 +151,20 @@ end
(* -- *)
let read_file fname = Bos.OS.File.read (Fpath.v fname) |> unwrap_msg
let read_file fname = Bos.OS.File.read (Fpath.v fname)
let write_file fname content = Bos.OS.File.write (Fpath.v fname) content
let write_file fname content =
Bos.OS.File.write (Fpath.v fname) content |> unwrap_msg
let write_json_file fname jsont v =
let* content = Api.encode jsont v in
write_file fname content
let read_master_key_file filename =
let* master_key = read_file filename in
Eddsa.priv_of_octets master_key
Eddsa.priv_of_octets master_key |> Result.map_error (fun e -> `Bin_decode e)
let download ~output ~url =
Result.unwrap_err
@@
let open Bos in
OS.Cmd.run
Cmd.(
@ -171,9 +177,10 @@ let download ~output ~url =
% "-X"
% "GET"
% url)
|> unwrap_msg
let upload ~input ~url =
Result.unwrap_err
@@
let open Bos in
OS.Cmd.run
Cmd.(
@ -189,31 +196,35 @@ let upload ~input ~url =
% "--data"
% ("@" ^ input)
% url)
|> unwrap_msg
let setup ~output ~output_pubkey =
Mirage_crypto_rng_unix.use_default ();
Result.unwrap_err
@@
let priv, pub = Mirage_crypto_ec.Ed25519.generate () in
let priv_data = Mirage_crypto_ec.Ed25519.priv_to_octets priv in
let* () = write_file output priv_data in
let pub_data = Mirage_crypto_ec.Ed25519.pub_to_octets pub |> B32.encode in
let* () = write_file output priv_data in
let* () = write_file output_pubkey pub_data in
Ok ()
let sign ~master_key ~input ~output =
Result.unwrap_err
@@
let* master_key = read_master_key_file master_key in
let* input = read_file input in
let master_pub = Eddsa.pub_of_priv master_key in
let* future_keys_response = Api.decode Api.FutureKeysResponse.jsont input in
let* () = Future_keys.verify master_pub future_keys_response in
let master_signatures = Future_keys.make ~master_key future_keys_response in
let* s = Api.encode Api.MasterSignatures.jsont master_signatures in
let* () = write_file output s in
Ok ()
write_json_file output Api.MasterSignatures.jsont master_signatures
let revoke_denom ~output ~master_key ~h_denom =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let* h_denom_pub = DenominationHash.of_b32 h_denom in
let* h_denom_pub =
DenominationHash.of_b32 h_denom |> Result.map_error (fun e -> `Msg e)
in
let denom_revoke =
let master_sig =
let open Signatures.MasterDenominationKeyRevocation in
@ -221,11 +232,11 @@ let revoke_denom ~output ~master_key ~h_denom =
in
Api.DenomRevocationSignature.{ master_sig }
in
let* s = Api.encode Api.DenomRevocationSignature.jsont denom_revoke in
let* () = write_file output s in
Ok ()
write_json_file output Api.DenomRevocationSignature.jsont denom_revoke
let revoke_signkey ~output ~master_key ~signkey =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let signkey_revoke =
let master_sig =
@ -234,20 +245,20 @@ let revoke_signkey ~output ~master_key ~signkey =
in
Api.SignkeyRevocationSignature.{ master_sig }
in
let* s = Api.encode Api.SignkeyRevocationSignature.jsont signkey_revoke in
let* () = write_file output s in
Ok ()
write_json_file output Api.SignkeyRevocationSignature.jsont signkey_revoke
let global_fees ~output ~master_key ~start_date ~end_date ~history_fee
~account_fee ~purse_fee ~history_expiration ~purse_account_limit
~purse_timeout =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let* purse_account_limit =
match
purse_account_limit >= 0
&& purse_account_limit <= Int32.to_int Int32.max_int
with
| false -> Error "invalid purse_account_limit value"
| false -> Fmt.error_msg "invalid purse_account_limit value"
| true -> Ok (Int32.of_int purse_account_limit)
in
let master_sig =
@ -278,11 +289,11 @@ let global_fees ~output ~master_key ~start_date ~end_date ~history_fee
master_sig;
}
in
let* s = Api.encode Api.GlobalFees.jsont global_fees in
let* () = write_file output s in
Ok ()
write_json_file output Api.GlobalFees.jsont global_fees
let enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let validity_start = Timestamp.of_s (now_s ()) in
let master_sig =
@ -298,11 +309,11 @@ let enable_auditor ~output ~master_key ~auditor_url ~auditor_name ~auditor_pub =
Api.AuditorSetupMessage.
{ auditor_url; auditor_name; auditor_pub; master_sig; validity_start }
in
let* s = Api.encode Api.AuditorSetupMessage.jsont v in
let* () = write_file output s in
Ok ()
write_json_file output Api.AuditorSetupMessage.jsont v
let disable_auditor ~output ~master_key ~auditor_pub =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let validity_end = TimeAbsolute.of_s (now_s ()) in
(* hack for tests: +1sec to be sure it overwrite previous timestamp *)
@ -314,12 +325,12 @@ let disable_auditor ~output ~master_key ~auditor_pub =
signf (Eddsa.sign ~key) { end_date= validity_end; auditor_pub }
in
let v = Api.AuditorTeardownMessage.{ master_sig; validity_end } in
let* s = Api.encode Api.AuditorTeardownMessage.jsont v in
let* () = write_file output s in
Ok ()
write_json_file output Api.AuditorTeardownMessage.jsont v
let wire_fee ~output ~master_key ~wire_method ~fee_start ~fee_end ~closing_fee
~wire_fee =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let master_sig_wire =
let open Signatures.MasterWireFee in
@ -343,11 +354,11 @@ let wire_fee ~output ~master_key ~wire_method ~fee_start ~fee_end ~closing_fee
master_sig_wire;
}
in
let* s = Api.encode Api.WireFeeSetupMessage.jsont v in
let* () = write_file output s in
Ok ()
write_json_file output Api.WireFeeSetupMessage.jsont v
let enable_wire ~output ~master_key ~payto_uri ~bank_label ~priority =
Result.unwrap_err
@@
(* TODO wire *)
let conversion_url = None in
let credit_restrictions = [] in
@ -396,11 +407,11 @@ let enable_wire ~output ~master_key ~payto_uri ~bank_label ~priority =
priority;
}
in
let* s = Api.encode Api.WireSetupMessage.jsont v in
let* () = write_file output s in
Ok ()
write_json_file output Api.WireSetupMessage.jsont v
let disable_wire ~output ~master_key ~payto_uri =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let validity_end = TimeAbsolute.of_s (now_s ()) in
(* hack for tests: +1sec to be sure it overwrite previous timestamp *)
@ -413,14 +424,16 @@ let disable_wire ~output ~master_key ~payto_uri =
signf (Eddsa.sign ~key) { end_date= validity_end; h_wire }
in
let v = Api.WireTeardownMessage.{ payto_uri; master_sig_del; validity_end } in
let* s = Api.encode Api.WireTeardownMessage.jsont v in
let* () = write_file output s in
Ok ()
write_json_file output Api.WireTeardownMessage.jsont v
let drain ~output ~master_key ~debit_account_section ~credit_payto_uri ~wtid
~date ~amount =
let drain ~output ~master_key ~debit_account_section ~credit_payto_uri
~wtid_octets ~date ~amount =
Result.unwrap_err
@@
let* key = read_master_key_file master_key in
let* wtid = Api.Bytes32.of_octets wtid in
let* wtid =
Api.Bytes32.of_octets wtid_octets |> Result.map_error (fun e -> `Msg e)
in
let master_sig =
let open Signatures.MasterDrainProfit in
signf (Eddsa.sign ~key)
@ -443,6 +456,4 @@ let drain ~output ~master_key ~debit_account_section ~credit_payto_uri ~wtid
amount;
}
in
let* s = Api.encode Api.DrainProfitsMessage.jsont v in
let* () = write_file output s in
Ok ()
write_json_file output Api.DrainProfitsMessage.jsont v