This document provides guidelines that should be observed by all the contributors to the Tezos codebase. It first presents documentation guidelines, and then rules more specific to coding (e.g., logging levels, code formatting, naming conventions, etc.).
The Tezos software is distributed under the MIT license. Every OCaml source file should start with a header comment instantiating the following template (use appropriate comment syntax for other languages):
(*****************************************************************************) (* *) (* MIT License *) (* Copyright (c) [year(s)] [Holder <email>] *) (* *) (* 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. *) (* *) (*****************************************************************************)
The holder, on the copyright line, is the name of the company which hires the employee or the sub-contractor.
For sub-contractors, check your specific contract terms. They sometimes allow to include, as an additional copyright holder, the name of a particular developer, but consider that this may end up with bloated license headers.
When adding a significant new contribution to a file (i.e. more like whole new features, rather than simple fixes), check whether there already is a copyright for your copyright holder (see above).
If there is one, mentioning any year, it is not required to add the current year (but this is allowed). In no case should you replace the existing year with the current one.
If there is no line for your copyright holder, you should add one, with the current year.
Old source files may contain on the first line Open Source License instead of MIT License. When touching such a file, please replace the former with the latter, correct form.
For example, for a source file with multiple contributors spanning several years, the copyright lines may look as follows:
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <firstname.lastname@example.org> *) (* Copyright (c) 2019-2020 Nomadic Labs <email@example.com> *) (* Copyright (c) 2020 Metastate AG <firstname.lastname@example.org> *)
Documenting interfaces and implementations¶
At the granularity of OCaml files, it is essential to document the interface implemented by each file. In many cases, it is useful to also document the implementation, but separately from the interface.
Document the interface:
In the common case where there is a corresponding interface (
.mli) file, document the interface file instead, as detailed below.
In the less common case where there is no corresponding interface (
.mli) file, document the exported elements directly in the implementation (
Document the implementation: For many non-trivial implementations, it is most useful to document the design principles, code structure, internal invariants, and so on. Such information should be placed in a comment block at the top of the file.
.mli) file comments:
Brief description of the library, introducing the needed concepts
Brief description of each module, type, function, data, as described for comments in the code
If applicable, external invariants (i.e., visible to the user).
At coarser levels, source file directories should be documented by Markdown files called
README.md. Such files are mandatory in top-level directories of the Tezos codebase (such as
docs/), and at least in immediate sub-directories of the source directory (
Source directories must instantiate the following
# Component Name <!-- Summary line: One sentence about this component. --> ## Overview <!-- - Describe the purpose of this component and how the code in this directory works. If needed, design rationale for its API. - Describe the interaction of the code in this directory with the other components. This includes dependencies on other components, for instance. - Describe the security model and assumptions about the crates in this directory. --> ## Implementation Details <!-- - Describe how the component is modeled. - Describe the code structure and implementation design rationale. - Other relevant implementation details (e.g. global invariants). - Testing specifics, if needed. --> ## API Documentation <!-- - Link to the external API. - For the top-level source directory, link to the most important APIs within. -->
The rationale of this template is that a README file addresses two different kinds of developers:
the users of the module, which are concerned only about the component concepts and API, and not about its implementations details, and
the developers and maintainers of the module, which are also concerned about implementation details.
When filling in the template, you should keep untouched the guidelines within HTML comments (which are visible to the document maintainers but invisible to end-users), so that any maintainer can check how well the README instantiates the template, and address any gap if needed.
The Tezos libraries use an internal logging library with 5 different verbosity levels. It is important to choose the appropriate level for each event in the code to avoid flooding the node administrator with too much information.
These are the rules-of-thumb that we use in the code to decide the appropriate level (here listed from most to least verbose) for each event:
Debuglevel – the most verbose – it is used by developers to follow the flow of execution of the node at the lowest granularity.
Infolevel is about all the additional information that you might want to have, but they are not important to have if your node is running OK (and definitely do not require any action).
Noticelevel (the default) should be about things that the node admin should be concerned, but that does not require any action.
The two following levels are used to provide information to the node administrator of possible problems and errors:
Warninglevel are all those events that might require the attention of the node administrator, and can reveal potential anomalies in the workings of the node.
Errorlevel are all those events that require an intervention of the node administrator or that signal some exceptional circumstance.
To ensure that your OCaml code is well formatted, set up correctly your editor:
automatically run ocamlformat when saving a file
no tabs, use whitespaces
no trailing whitespaces
indent correctly (e.g. use lisp-mode for dune files)
Many of these checks can be run with
Some of these checks can be executed with a pre-commit
which is installed with
ln -sr scripts/pre_commit/pre_commit.py .git/hooks/pre-commit
(see the header of ./scripts/pre_commit/pre_commit.py and its –help
for additional options).