From 5bfe8f90f2a2eefee4939e85176c95fdda1699de Mon Sep 17 00:00:00 2001 From: Benjamin Canou Date: Mon, 20 Mar 2017 18:11:43 +0100 Subject: [PATCH] Alpha: document and classify more errors. --- src/proto/alpha/apply.ml | 42 +++++++++++++++++++++++++----- src/proto/alpha/operation_repr.ml | 42 +++++++++++++++++++++++++++--- src/proto/alpha/operation_repr.mli | 6 +++-- src/proto/alpha/tezos_context.mli | 6 +++-- 4 files changed, 83 insertions(+), 13 deletions(-) diff --git a/src/proto/alpha/apply.ml b/src/proto/alpha/apply.ml index a1504d9c7..c8e3da27b 100644 --- a/src/proto/alpha/apply.ml +++ b/src/proto/alpha/apply.ml @@ -11,15 +11,45 @@ open Tezos_context -type error += Bad_endorsement (* TODO: doc *) -type error += Unimplemented -type error += Invalid_voting_period +type error += Wrong_voting_period of Voting_period.t * Voting_period.t (* `Temporary *) +type error += Wrong_endorsement_predecessor of Block_hash.t * Block_hash.t (* `Temporary *) + +let () = + register_error_kind + `Temporary + ~id:"operation.wrong_endorsement_predecessor" + ~title:"Wrong endorsement predecessor" + ~description:"Trying to include an endorsement in a block \ + that is not the successor of the endorsed one" + ~pp:(fun ppf (e, p) -> + Format.fprintf ppf "Wrong predecessor %a, expected %a" + Block_hash.pp p Block_hash.pp e) + Data_encoding.(obj2 + (req "expected" Block_hash.encoding) + (req "provided" Block_hash.encoding)) + (function Wrong_endorsement_predecessor (e, p) -> Some (e, p) | _ -> None) + (fun (e, p) -> Wrong_endorsement_predecessor (e, p)) ; + register_error_kind + `Temporary + ~id:"operation.wrong_voting_period" + ~title:"Wrong voting period" + ~description:"Trying to onclude a proposal or ballot \ + meant for another voting period" + ~pp:(fun ppf (e, p) -> + Format.fprintf ppf "Wrong voting period %a, current is %a" + Voting_period.pp p Voting_period.pp e) + Data_encoding.(obj2 + (req "current" Voting_period.encoding) + (req "provided" Voting_period.encoding)) + (function Wrong_voting_period (e, p) -> Some (e, p) | _ -> None) + (fun (e, p) -> Wrong_voting_period (e, p)) let apply_delegate_operation_content ctxt delegate pred_block block_priority = function | Endorsement { block ; slot } -> fail_unless - (Block_hash.equal block pred_block) Bad_endorsement >>=? fun () -> + (Block_hash.equal block pred_block) + (Wrong_endorsement_predecessor (pred_block, block)) >>=? fun () -> Mining.check_signing_rights ctxt slot delegate >>=? fun () -> Fitness.increase ctxt >>=? fun ctxt -> Mining.pay_endorsement_bond ctxt delegate >>=? fun (ctxt, bond) -> @@ -30,12 +60,12 @@ let apply_delegate_operation_content | Proposals { period ; proposals } -> Level.current ctxt >>=? fun level -> fail_unless Voting_period.(level.voting_period = period) - Invalid_voting_period >>=? fun () -> + (Wrong_voting_period (level.voting_period, period)) >>=? fun () -> Amendment.record_proposals ctxt delegate proposals | Ballot { period ; proposal ; ballot } -> Level.current ctxt >>=? fun level -> fail_unless Voting_period.(level.voting_period = period) - Invalid_voting_period >>=? fun () -> + (Wrong_voting_period (level.voting_period, period)) >>=? fun () -> Amendment.record_ballot ctxt delegate proposal ballot let rec is_reject = function diff --git a/src/proto/alpha/operation_repr.ml b/src/proto/alpha/operation_repr.ml index 824465a30..710745ce8 100644 --- a/src/proto/alpha/operation_repr.ml +++ b/src/proto/alpha/operation_repr.ml @@ -321,6 +321,19 @@ end type error += Cannot_parse_operation +let () = + register_error_kind + `Branch + ~id:"operation.cannot_parse" + ~title:"Cannot parse operation" + ~description:"The operation is ill-formed \ + or for another protocol version" + ~pp:(fun ppf () -> + Format.fprintf ppf "The operation cannot be parsed") + Data_encoding.unit + (function Cannot_parse_operation -> Some () | _ -> None) + (fun () -> Cannot_parse_operation) + let parse hash (op: Updater.raw_operation) = if not (Compare.Int.(MBytes.length op.proto <= Constants_repr.max_operation_data_length)) then error Cannot_parse_operation @@ -333,9 +346,32 @@ let parse hash (op: Updater.raw_operation) = ok { hash ; shell ; contents ; signature } | None -> error Cannot_parse_operation -type error += - | Invalid_signature - | Missing_signature +type error += Invalid_signature (* `Permanent *) +type error += Missing_signature (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"operation.invalid_signature" + ~title:"Invalid operation signature" + ~description:"The operation signature is ill-formed \ + or has been made with the wrong public key" + ~pp:(fun ppf () -> + Format.fprintf ppf "The operation signature is invalid") + Data_encoding.unit + (function Invalid_signature -> Some () | _ -> None) + (fun () -> Invalid_signature) ; + register_error_kind + `Permanent + ~id:"operation.missing_signature" + ~title:"Missing operation signature" + ~description:"The operation is of a kind that must be signed, \ + but the signature is missing" + ~pp:(fun ppf () -> + Format.fprintf ppf "The operation requires a signature") + Data_encoding.unit + (function Missing_signature -> Some () | _ -> None) + (fun () -> Missing_signature) let forge shell proto = Data_encoding.Binary.to_bytes diff --git a/src/proto/alpha/operation_repr.mli b/src/proto/alpha/operation_repr.mli index 918af3da0..1b19522f4 100644 --- a/src/proto/alpha/operation_repr.mli +++ b/src/proto/alpha/operation_repr.mli @@ -81,7 +81,7 @@ and dictator_operation = and counter = Int32.t -type error += Cannot_parse_operation +type error += Cannot_parse_operation (* `Branch *) val parse: Operation_hash.t -> Updater.raw_operation -> operation tzresult @@ -90,7 +90,9 @@ val parse_proto: MBytes.t -> (proto_operation * Ed25519.Signature.t option) tzresult Lwt.t -type error += Invalid_signature +type error += Missing_signature (* `Permanent *) +type error += Invalid_signature (* `Permanent *) + val check_signature: Ed25519.Public_key.t -> operation -> unit tzresult Lwt.t diff --git a/src/proto/alpha/tezos_context.mli b/src/proto/alpha/tezos_context.mli index 2280b9d98..ee3f3585d 100644 --- a/src/proto/alpha/tezos_context.mli +++ b/src/proto/alpha/tezos_context.mli @@ -493,14 +493,16 @@ and counter = Int32.t module Operation : sig - type error += Cannot_parse_operation + type error += Cannot_parse_operation (* `Branch *) val parse: Operation_hash.t -> Updater.raw_operation -> operation tzresult val parse_proto: MBytes.t -> (proto_operation * signature option) tzresult Lwt.t - type error += Invalid_signature + type error += Missing_signature (* `Permanent *) + type error += Invalid_signature (* `Permanent *) + val check_signature: public_key -> operation -> unit tzresult Lwt.t val forge: Updater.shell_operation -> proto_operation -> MBytes.t