2018-06-29 16:08:08 +04:00
|
|
|
(*****************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Open Source License *)
|
|
|
|
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* Permission is hereby granted, free of charge, to any person obtaining a *)
|
|
|
|
(* copy of this software and associated documentation files (the "Software"),*)
|
|
|
|
(* to deal in the Software without restriction, including without limitation *)
|
|
|
|
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
|
|
|
|
(* and/or sell copies of the Software, and to permit persons to whom the *)
|
|
|
|
(* Software is furnished to do so, subject to the following conditions: *)
|
|
|
|
(* *)
|
|
|
|
(* The above copyright notice and this permission notice shall be included *)
|
|
|
|
(* in all copies or substantial portions of the Software. *)
|
|
|
|
(* *)
|
|
|
|
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
|
|
|
|
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
|
|
|
|
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
|
|
|
|
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
|
|
|
|
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
|
|
|
|
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
|
|
|
|
(* DEALINGS IN THE SOFTWARE. *)
|
|
|
|
(* *)
|
|
|
|
(*****************************************************************************)
|
2018-02-13 17:12:09 +04:00
|
|
|
|
|
|
|
(***************** Prevalidation errors ***********************************)
|
|
|
|
|
|
|
|
type error += Parse_error
|
|
|
|
type error += Too_many_operations
|
|
|
|
type error += Oversized_operation of { size: int ; max: int }
|
2018-06-14 15:27:39 +04:00
|
|
|
type error += Future_block_header of { block: Block_hash.t ; block_time : Time.t ; time : Time.t }
|
2018-02-13 17:12:09 +04:00
|
|
|
|
|
|
|
let () =
|
|
|
|
(* Parse error *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.prevalidation.parse_error"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Parsing error in prevalidation"
|
|
|
|
~description:"Raised when an operation has not been parsed correctly during prevalidation."
|
|
|
|
~pp:(fun ppf () ->
|
|
|
|
Format.fprintf ppf "Operation parsing error in prevalidation.")
|
|
|
|
Data_encoding.empty
|
|
|
|
(function Parse_error -> Some () | _ -> None)
|
|
|
|
(fun () -> Parse_error) ;
|
|
|
|
(* Too many operations *)
|
|
|
|
register_error_kind
|
|
|
|
`Temporary
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.prevalidation.too_many_operations"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Too many pending operations in prevalidation"
|
|
|
|
~description:"The prevalidation context is full."
|
|
|
|
~pp:(fun ppf () ->
|
|
|
|
Format.fprintf ppf "Too many operations in prevalidation context.")
|
|
|
|
Data_encoding.empty
|
|
|
|
(function Too_many_operations -> Some () | _ -> None)
|
|
|
|
(fun () -> Too_many_operations) ;
|
|
|
|
(* Oversized operation *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.prevalidation.oversized_operation"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Oversized operation"
|
|
|
|
~description:"The operation size is bigger than allowed."
|
|
|
|
~pp:(fun ppf (size, max) ->
|
|
|
|
Format.fprintf ppf "Oversized operation (size: %d, max: %d)"
|
|
|
|
size max)
|
|
|
|
Data_encoding.(obj2
|
|
|
|
(req "size" int31)
|
|
|
|
(req "max_size" int31))
|
|
|
|
(function Oversized_operation { size ; max } -> Some (size, max) | _ -> None)
|
2018-06-14 15:27:39 +04:00
|
|
|
(fun (size, max) -> Oversized_operation { size ; max }) ;
|
|
|
|
(* Block from the future *)
|
|
|
|
register_error_kind
|
|
|
|
`Temporary
|
|
|
|
~id:"node.prevalidation.future_block_header"
|
|
|
|
~title:"Future block header"
|
|
|
|
~description:"The block was annotated with a time too far in the future."
|
|
|
|
~pp:(fun ppf (block, block_time, time) ->
|
|
|
|
Format.fprintf ppf "Future block header (block: %a, block_time: %a, time: %a)"
|
|
|
|
Block_hash.pp block Time.pp_hum block_time Time.pp_hum time)
|
|
|
|
Data_encoding.(obj3
|
|
|
|
(req "block" Block_hash.encoding)
|
|
|
|
(req "block_time" Time.encoding)
|
|
|
|
(req "time" Time.encoding))
|
|
|
|
(function Future_block_header { block ; block_time ; time } -> Some (block, block_time, time) | _ -> None)
|
|
|
|
(fun (block, block_time, time) -> Future_block_header { block ; block_time ; time })
|
2018-02-13 17:12:09 +04:00
|
|
|
|
|
|
|
|
|
|
|
(************************* State errors ***********************************)
|
|
|
|
|
|
|
|
type error += Unknown_chain of Chain_id.t
|
|
|
|
|
|
|
|
type error += Bad_data_dir
|
|
|
|
|
|
|
|
type error += Block_not_invalid of Block_hash.t
|
|
|
|
|
|
|
|
let () =
|
|
|
|
(* Unknown network *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.state.unknown_chain"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Unknown chain"
|
|
|
|
~description:"The chain identifier could not be found in \
|
|
|
|
the chain identifiers table."
|
|
|
|
~pp:(fun ppf id ->
|
|
|
|
Format.fprintf ppf "Unknown chain %a" Chain_id.pp id)
|
|
|
|
Data_encoding.(obj1 (req "chain" Chain_id.encoding))
|
|
|
|
(function Unknown_chain x -> Some x | _ -> None)
|
|
|
|
(fun x -> Unknown_chain x) ;
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.state.bad_data_dir"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Bad data directory"
|
|
|
|
~description:"The data directory could not be read. \
|
|
|
|
This could be because it was generated with an \
|
|
|
|
old version of the tezos-node program. \
|
|
|
|
Deleting and regenerating this directory \
|
|
|
|
may fix the problem."
|
|
|
|
~pp:(fun ppf () -> Format.fprintf ppf "Bad data directory.")
|
|
|
|
Data_encoding.empty
|
|
|
|
(function Bad_data_dir -> Some () | _ -> None)
|
|
|
|
(fun () -> Bad_data_dir) ;
|
|
|
|
(* Block not invalid *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.state.block_not_invalid"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Block not invalid"
|
|
|
|
~description:"The invalid block to be unmarked was not actually invalid."
|
|
|
|
~pp:(fun ppf block ->
|
|
|
|
Format.fprintf ppf "Block %a was expected to be invalid, but was not actually invalid."
|
|
|
|
Block_hash.pp block)
|
|
|
|
Data_encoding.(obj1 (req "block" Block_hash.encoding))
|
|
|
|
(function Block_not_invalid block -> Some block | _ -> None)
|
|
|
|
(fun block -> Block_not_invalid block)
|
|
|
|
|
|
|
|
(* Block database error *)
|
|
|
|
|
|
|
|
type error += Inconsistent_hash of Context_hash.t * Context_hash.t
|
|
|
|
|
|
|
|
let () =
|
|
|
|
(* Inconsistent hash *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.state.block.inconsistent_context_hash"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Inconsistent commit hash"
|
|
|
|
~description:
|
|
|
|
"When commiting the context of a block, the announced context \
|
|
|
|
hash was not the one computed at commit time."
|
|
|
|
~pp: (fun ppf (got, exp) ->
|
|
|
|
Format.fprintf ppf
|
|
|
|
"@[<v 2>Inconsistant hash:@ got: %a@ expected: %a"
|
|
|
|
Context_hash.pp got
|
|
|
|
Context_hash.pp exp)
|
|
|
|
Data_encoding.(obj2
|
|
|
|
(req "wrong_context_hash" Context_hash.encoding)
|
|
|
|
(req "expected_context_hash" Context_hash.encoding))
|
|
|
|
(function Inconsistent_hash (got, exp) -> Some (got, exp) | _ -> None)
|
|
|
|
(fun (got, exp) -> Inconsistent_hash (got, exp))
|
|
|
|
|
|
|
|
(******************* Bootstrap pipeline errors ****************************)
|
|
|
|
|
|
|
|
type error += Invalid_locator of P2p_peer.Id.t * Block_locator.t
|
|
|
|
|
|
|
|
let () =
|
|
|
|
(* Invalid locator *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.bootstrap_pipeline.invalid_locator"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Invalid block locator"
|
|
|
|
~description:"Block locator is invalid."
|
|
|
|
~pp: (fun ppf (id, locator) ->
|
|
|
|
Format.fprintf ppf
|
2018-02-19 21:25:57 +04:00
|
|
|
"Invalid block locator on peer %a:\n%a"
|
|
|
|
P2p_peer.Id.pp id
|
|
|
|
Block_locator.pp locator)
|
2018-02-13 17:12:09 +04:00
|
|
|
Data_encoding.(obj2
|
|
|
|
(req "id" P2p_peer.Id.encoding)
|
|
|
|
(req "locator" Block_locator.encoding))
|
|
|
|
(function | Invalid_locator (id, loc) -> Some (id, loc) | _ -> None)
|
|
|
|
(fun (id, loc) -> Invalid_locator (id, loc))
|
|
|
|
|
|
|
|
(******************* Protocol validator errors ****************************)
|
|
|
|
|
|
|
|
type protocol_error =
|
|
|
|
| Compilation_failed
|
|
|
|
| Dynlinking_failed
|
|
|
|
|
|
|
|
type error += Invalid_protocol of { hash: Protocol_hash.t ; error: protocol_error }
|
|
|
|
|
|
|
|
let protocol_error_encoding =
|
|
|
|
let open Data_encoding in
|
|
|
|
union
|
|
|
|
[
|
|
|
|
case (Tag 0)
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Compilation failed"
|
2018-02-13 17:12:09 +04:00
|
|
|
(obj1
|
|
|
|
(req "error" (constant "compilation_failed")))
|
|
|
|
(function Compilation_failed -> Some ()
|
|
|
|
| _ -> None)
|
|
|
|
(fun () -> Compilation_failed) ;
|
|
|
|
case (Tag 1)
|
2018-06-01 01:19:43 +04:00
|
|
|
~title:"Dynlinking failed"
|
2018-02-13 17:12:09 +04:00
|
|
|
(obj1
|
|
|
|
(req "error" (constant "dynlinking_failed")))
|
|
|
|
(function Dynlinking_failed -> Some ()
|
|
|
|
| _ -> None)
|
|
|
|
(fun () -> Dynlinking_failed) ;
|
|
|
|
]
|
|
|
|
|
|
|
|
let pp_protocol_error ppf = function
|
|
|
|
| Compilation_failed ->
|
|
|
|
Format.fprintf ppf "compilation error"
|
|
|
|
| Dynlinking_failed ->
|
|
|
|
Format.fprintf ppf "dynlinking error"
|
|
|
|
|
|
|
|
let () =
|
|
|
|
(* Invalid protocol *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
2018-02-18 20:33:29 +04:00
|
|
|
~id:"node.protocol_validator.invalid_protocol"
|
2018-02-13 17:12:09 +04:00
|
|
|
~title:"Invalid protocol"
|
|
|
|
~description:"Invalid protocol."
|
|
|
|
~pp:begin fun ppf (protocol, error) ->
|
|
|
|
Format.fprintf ppf
|
|
|
|
"@[<v 2>Invalid protocol %a@ %a@]"
|
|
|
|
Protocol_hash.pp_short protocol pp_protocol_error error
|
|
|
|
end
|
|
|
|
Data_encoding.(merge_objs
|
|
|
|
(obj1 (req "invalid_protocol" Protocol_hash.encoding))
|
|
|
|
protocol_error_encoding)
|
|
|
|
(function Invalid_protocol { hash ; error } ->
|
|
|
|
Some (hash, error) | _ -> None)
|
|
|
|
(fun (hash, error) ->
|
|
|
|
Invalid_protocol { hash ; error })
|
|
|
|
|
|
|
|
(********************* Peer validator errors ******************************)
|
|
|
|
|
|
|
|
type error +=
|
|
|
|
| Unknown_ancestor
|
|
|
|
| Known_invalid
|
|
|
|
|
|
|
|
let () =
|
|
|
|
(* Unknown ancestor *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
|
|
|
~id: "node.peer_validator.unknown_ancestor"
|
|
|
|
~title: "Unknown ancestor"
|
|
|
|
~description: "Unknown ancestor block found in the peer's chain"
|
|
|
|
~pp: (fun ppf () -> Format.fprintf ppf "Unknown ancestor")
|
|
|
|
Data_encoding.empty
|
|
|
|
(function Unknown_ancestor -> Some () | _ -> None)
|
|
|
|
(fun () -> Unknown_ancestor) ;
|
|
|
|
(* Known invalid *)
|
|
|
|
register_error_kind
|
|
|
|
`Permanent
|
|
|
|
~id: "node.peer_validator.known_invalid"
|
|
|
|
~title: "Known invalid"
|
|
|
|
~description: "Known invalid block found in the peer's chain"
|
|
|
|
~pp: (fun ppf () -> Format.fprintf ppf "Known invalid")
|
|
|
|
Data_encoding.empty
|
|
|
|
(function Known_invalid -> Some () | _ -> None)
|
|
|
|
(fun () -> Known_invalid)
|
|
|
|
|
|
|
|
(************************ Validator errors ********************************)
|
|
|
|
|
|
|
|
type error += Inactive_chain of Chain_id.t
|
2018-05-10 18:40:36 +04:00
|
|
|
type error += Checkpoint_error of Block_hash.t * P2p_peer.Id.t option
|
2018-02-13 17:12:09 +04:00
|
|
|
|
|
|
|
let () =
|
|
|
|
(* Inactive network *)
|
|
|
|
register_error_kind
|
|
|
|
`Branch
|
|
|
|
~id: "node.validator.inactive_chain"
|
|
|
|
~title: "Inactive chain"
|
|
|
|
~description: "Attempted validation of a block from an inactive chain."
|
|
|
|
~pp: (fun ppf chain ->
|
|
|
|
Format.fprintf ppf
|
|
|
|
"Tried to validate a block from chain %a, \
|
|
|
|
that is not currently considered active."
|
|
|
|
Chain_id.pp chain)
|
|
|
|
Data_encoding.(obj1 (req "inactive_chain" Chain_id.encoding))
|
|
|
|
(function Inactive_chain chain -> Some chain | _ -> None)
|
2018-05-10 18:40:36 +04:00
|
|
|
(fun chain -> Inactive_chain chain) ;
|
|
|
|
register_error_kind
|
|
|
|
`Branch
|
|
|
|
~id:"node.validator.checkpoint_error"
|
|
|
|
~title: "Block incompatble with the current checkpoint."
|
|
|
|
~description: "The block belongs to a branch that is not compatible \
|
|
|
|
with the current checkpoint."
|
|
|
|
~pp: (fun ppf (block, peer) ->
|
|
|
|
match peer with
|
|
|
|
| None ->
|
|
|
|
Format.fprintf ppf
|
|
|
|
"The block %a is incompatible with the current checkpoint."
|
|
|
|
Block_hash.pp_short block
|
|
|
|
| Some peer ->
|
|
|
|
Format.fprintf ppf
|
|
|
|
"The peer %a send us a block which is a sibling \
|
|
|
|
of the configured checkpoint (%a)."
|
|
|
|
P2p_peer.Id.pp peer
|
|
|
|
Block_hash.pp_short block)
|
|
|
|
Data_encoding.(obj2
|
|
|
|
(req "block" Block_hash.encoding)
|
|
|
|
(opt "peer" P2p_peer.Id.encoding))
|
|
|
|
(function Checkpoint_error (block, peer) -> Some (block, peer) | _ -> None)
|
|
|
|
(fun (block, peer) -> Checkpoint_error (block, peer))
|
|
|
|
|