├── .gitignore ├── .gitmodules ├── Cargo.toml ├── LICENSE ├── README.md ├── cargo-move └── moved.md ├── cargo-movemint ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── src │ ├── application.rs │ ├── bin │ │ └── cargo-movemint │ │ │ └── main.rs │ ├── commands.rs │ ├── commands │ │ ├── start.rs │ │ └── version.rs │ ├── config.rs │ ├── error.rs │ ├── lib.rs │ └── prelude.rs └── tests │ └── acceptance.rs ├── docs ├── Components.md ├── GitStrategy.md ├── L_OL_∆.png ├── Roadmap.md ├── TCB.md ├── crev.md └── tlog-rust-move.md ├── protofiles ├── abci │ ├── abci.proto │ ├── github.com │ │ ├── gogo │ │ │ └── protobuf │ │ │ │ └── gogoproto │ │ │ │ └── gogo.proto │ │ └── tendermint │ │ │ └── tendermint │ │ │ ├── abci │ │ │ └── types │ │ │ │ └── types.proto │ │ │ ├── crypto │ │ │ └── merkle │ │ │ │ └── merkle.proto │ │ │ └── libs │ │ │ └── common │ │ │ └── types.proto │ └── google │ │ └── protobuf │ │ ├── descriptor.proto │ │ └── timestamp.proto ├── lc │ ├── access_path.proto │ ├── account_state_blob.proto │ ├── admission_control.proto │ ├── consensus.proto │ ├── crates │ │ ├── admission-control.md │ │ ├── bytecode-verifier.md │ │ ├── consensus.md │ │ ├── crypto.md │ │ ├── execution.md │ │ ├── ir-to-bytecode.md │ │ ├── mempool.md │ │ ├── move-language.md │ │ ├── network.md │ │ ├── storage.md │ │ └── vm.md │ ├── events.proto │ ├── execution.proto │ ├── get_with_proof.proto │ ├── language_storage.proto │ ├── ledger_info.proto │ ├── mempool.proto │ ├── mempool_status.proto │ ├── network.proto │ ├── node_debug_interface.proto │ ├── proof.proto │ ├── secret_service.proto │ ├── state_synchronizer.proto │ ├── storage.proto │ ├── test.proto │ ├── transaction.proto │ ├── transaction_info.proto │ ├── validator_change.proto │ ├── validator_public_keys.proto │ ├── validator_set.proto │ └── vm_errors.proto └── trillian │ ├── trillian.proto │ ├── trillian_admin_api.proto │ ├── trillian_log_api.proto │ ├── trillian_log_sequencer_api.proto │ └── trillian_map_api.proto └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/libra-core"] 2 | path = src/libra-core 3 | url = https://github.com/libra/libra 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "movemint" 3 | version = "0.0.0" 4 | authors = ["LOL"] 5 | publish = false 6 | edition = "2018" 7 | 8 | [dependencies] 9 | vm_runtime = { path = "./src/libra-core/language/vm/vm_runtime/" } 10 | config = { path = "./src/libra-core/config/" } 11 | 12 | [dependencies.abci] 13 | version = "0.6.2" 14 | 15 | [dependencies.abscissa_core] 16 | version = "0.3.0" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # movemint 2 | Move VM on Tendermint 3 | 4 | Table of contents: 5 | - [Overview](#Overview) 6 | - [Dependencies and TCB](#Dependencies-and-TCB) 7 | - [Repo Structure](#Repo-Structure) 8 | - [Running the Placeholder App](#Running-the-Placeholder-App) 9 | - [Join the Movemint!](#Join-the-Movemint) 10 | - [Contributing](#Contributing) 11 | - [Research](#Research) 12 | - [Our Strategy](#Our-Strategy) 13 | - [From Golang to Rust and Move](#From-Golang-to-Rust-and-Move) 14 | - [Protobuf + gRPC](#Protobuf-+-gRPC) 15 | 16 | # Overview 17 | 18 | This is the genesis repo for `movemint` which is being built by replacing the [SMR] Module of [Libra Core] with [Tendermint]. We'll use *LC* to refer to Libra Core henceforth. 19 | 20 | Movemint talks to Tendermint via the [ABCI]. 21 | 22 | Movemint will primarily depend on the Move language [crate] from LC. A hat-tip to the LC authors and the [Libra Association]! 23 | 24 | When complete, Movemint may serve as node software for 1 or more Tendermint-powered networks. Some of these networks may join the [Cosmos] network. 25 | 26 | Movemint is a project of the [OL] collective. OL is grateful for grant funding from the [ICF]. 27 | 28 | See the [Roadmap] to learn more about where we're headed. 29 | 30 | # Dependencies and TCB 31 | 32 | The current design of Movemint makes use of [rust-abci] for ABCI, [Abscissa] for CLI (and component management), as well as the [Tokio] runtime. (Tokio along with an Actor model is used in LC's `mempool` and `consensus` components.) 33 | 34 | As it stands, [Move] is not available as a crate so we have opted to include LC as a git submodule. This should change once the Libra Core components are published on a registry (like crates.io). See the [GitStrategy] doc for more info on our upstream/downstream strategy. 35 | 36 | We are focused on minimal dependencies (read [TCB]). Read more on the TCB philosophy from the Libra Assosciation blog: [The Path Forward]. One way of looking at movemint is as an LC-compatible implementation with a different (read smaller) TCB. 37 | 38 | We'll have more to say on the notion of TCB as it pertains to Movemint vs. LC. 39 | 40 | # Repo Structure 41 | 42 | ``` 43 | ├── cargo-move 44 | ├── cargo-movemint 45 | ├── docs 46 | ├── protofiles 47 | └── src 48 | ├── libra-core # git submodule 49 | └── main.rs 50 | ``` 51 | 52 | # Running the Placeholder App 53 | 54 | Make sure you have installed [Git], [Rust]/[Cargo], and [Tendermint]. 55 | 56 | Clone this repo: 57 | 58 | `git clone https://github.com/open-libra/movemint` 59 | 60 | Update the Libra Core submodule. `cd` into the cloned repo and run: `git submodule update --init --recursive` 61 | 62 | Then build movemint: `cargo build` 63 | 64 | To run it, open two windows: 65 | 66 | on the 1st, run: `cargo run movemint` 67 | 68 | on the 2nd, run: `tendermint init` and then `tendermint node` 69 | 70 | You will see that the dummy `movemint` app connects to Tendermint via ABCI. There is an *unused* MoveVM instance that is to be used to validate, verify, and execute transactions (TODO!). 71 | 72 | In the coming weeks we will be fleshing out this repository with code and documentation. See the [Components] doc to learn more about tools we are building. 73 | 74 | # Join the Movemint 75 | 76 | Now, you may want to join us as we work hard to make `movemint` a reality! Jump to the `Research` section; it may give you ideas to contribute as code or documentation! 77 | 78 | # Contributing 79 | 80 | Use standard GitHub practices. Fork this repository. Clone to your machine. Branch from the tip, etc. 81 | 82 | `git checkout -b my_awesome_contribution_to_the_movemint` 83 | 84 | Code away, commit, test, and push to GitHub. 85 | 86 | Finally, when you're ready to merge, please submit a PR. We will promptly review the code and (if all goes well) we'll merge it to master! 87 | 88 | # Research 89 | 90 | For the past few months we've been busy doing research on the Libra ecosystem: papers, codebase, community, et cetera. 91 | 92 | ## Our Strategy 93 | 94 | We have come up with a **∆ strategy** wherein the `Move VM` serves as `compatibility layer` between a Movemint network and an LC network. 95 | 96 | We will publish a blog about this ∆-ular strategy of 'unpacking trust in Libra'. 97 | 98 | Note that [TCB] is a term used in the trusted computing domain. 99 | 100 | ![∆](docs/L_OL_∆.png) 101 | 102 | ## From Golang to Rust and Move 103 | 104 | The Tendermint/Cosmos ecosystem is increasingly adopting Rust. The [rust-abci] and [tendermint-rs] crates are good examples. There are also tools like `kms` and `sagan` built for Tendermint in Rust. We hope to contribute to the Cosmos Rust SDK in the process of building Movemint (e.g. a Rust equivalent of the Cosmos Go SDK's [BaseApp]). 105 | 106 | The Golang team has recently introduced the [Go checksum] database (built on [Trillian]): 107 | 108 | Being able to authenticate a particular module version download effectively moves code hosting servers like rsc.io and github.com out of the trusted computing base [TCB] of the Go module ecosystem. 109 | 110 | Introducing a similar checksum DB to Rust (e.g. in crates.io) and to `Move` itself is within our [Roadmap]. This is beneficial to the Rust community at large as well as the nascent Move language ecosystem. More importantly, it allows Move-compatible financial networks to share Move packages in a trustworthy fashion. We'll explain our rationale and design goals in the [tlog-rust-move] doc. 111 | 112 | `Cargo` is a powerful tool into which we can introduce checksum database checking and more. To this end, we're building a `movemint`-specific plugin and a general purpose plugin to work with Move code from within Cargo. These are found in `./cargo-movemint` and `./cargo-move` directories, respectively. Both plugins are to be built with the [Abscissa] framework (h/t [@bascule](https://twitter.com/bascule)). 113 | 114 | ## Protobuf + gRPC 115 | 116 | Last but not least, the `protofiles` directory is a repository of protobuf files extracted from LC, Tendermint/ABCI, and [Trillian] for convenience. Note that the last 2 are implemented in Golang whereas LC is written in Rust. We encourage researchers and developers planning to work on Movemint to familiarize themselves with the protobuf/[gRPC] files in the `abci` and `lc` directories first. (The `trillian` directory will come in handy too, in the near future!) 117 | 118 | The 3 directories roughly correspond to 3 points in a triangle, hence the `∆` in our strategy. 119 | 120 | ----- 121 | 122 | DISCLAIMER 123 | 124 | _THERE MAY BE DRAGONS._ 125 | 126 | All content in this repo including the README is licensed under Apache-2.0. 127 | 128 | ----- 129 | 130 | [crate]: https://developers.libra.org/docs/crates/vm 131 | [crates.io]: https://crates.io 132 | [Libra Core]: https://github.com/libra/libra 133 | [The Path Forward]: https://developers.libra.org/blog/2019/06/18/the-path-forward 134 | [Libra Association]: https://libra.org 135 | 136 | [OL]: https://openlibra.io 137 | [Discord]: https://discord.gg/wXHHxD 138 | 139 | [SMR]: https://en.wikipedia.org/wiki/State_machine_replication 140 | [Move]: https://developers.libra.org/docs/move-paper 141 | 142 | [Tendermint]: https://tendermint.com 143 | [tendermint-rs]: https://crates.io/crates/tendermint 144 | [ABCI]: https://tendermint.com/docs/spec/abci/ 145 | [rust-abci]: https://crates.io/crates/abci 146 | [Cosmos]: https://cosmos.network 147 | [BaseApp]: https://github.com/cosmos/cosmos-sdk/tree/master/baseapp 148 | [ICF]: https://interchain.io 149 | 150 | [TCB]: https://en.wikipedia.org/wiki/Trusted_computing_base 151 | 152 | [Abscissa]: https://iqlusion.blog/introducing-abscissa-rust-application-framework 153 | [Tokio]: https://tokio.rs/ 154 | [gRPC]: https://grpc.io 155 | 156 | [Trillian]: https://github.com/google/trillian 157 | [Go checksum]: https://go.googlesource.com/proposal/+/master/design/25530-sumdb.md 158 | [Trillian Rust API]: https://twitter.com/BenLaurie/status/1167335026507337730 159 | 160 | [tlog-rust-move]: docs/tlog-rust-move.md 161 | [Components]: docs/Components.md 162 | [GitStrategy]: docs/GitStrategy.md 163 | [Roadmap]: docs/Roadmap.md 164 | 165 | [Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git 166 | [Rust]: https://rust-lang.org 167 | [Cargo]: https://doc.rust-lang.org/cargo/getting-started/installation.html 168 | -------------------------------------------------------------------------------- /cargo-move/moved.md: -------------------------------------------------------------------------------- 1 | This crate has been [moved]. 2 | 3 | [moved]: https://github.com/open-libra/movemint/commit/28d70c1135f79611b50a5b8b2d36308cbf82fcb2 4 | -------------------------------------------------------------------------------- /cargo-movemint/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /cargo-movemint/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "abscissa_core" 5 | version = "0.3.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | dependencies = [ 8 | "abscissa_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "canonical-path 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 12 | "generational-arena 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 13 | "gumdrop 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 17 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 18 | "secrecy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 19 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 20 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 21 | "signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 22 | "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 23 | "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 24 | "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 25 | ] 26 | 27 | [[package]] 28 | name = "abscissa_derive" 29 | version = "0.3.0" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | dependencies = [ 32 | "darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 33 | "ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 34 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 35 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 37 | "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", 38 | ] 39 | 40 | [[package]] 41 | name = "aho-corasick" 42 | version = "0.7.6" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | dependencies = [ 45 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 46 | ] 47 | 48 | [[package]] 49 | name = "arc-swap" 50 | version = "0.4.3" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | 53 | [[package]] 54 | name = "autocfg" 55 | version = "0.1.6" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | 58 | [[package]] 59 | name = "backtrace" 60 | version = "0.3.38" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | dependencies = [ 63 | "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 64 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 65 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 66 | "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 67 | ] 68 | 69 | [[package]] 70 | name = "backtrace-sys" 71 | version = "0.1.31" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | dependencies = [ 74 | "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", 75 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 76 | ] 77 | 78 | [[package]] 79 | name = "canonical-path" 80 | version = "2.0.2" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | 83 | [[package]] 84 | name = "cargo-movemint" 85 | version = "0.0.0" 86 | dependencies = [ 87 | "abscissa_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 88 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 89 | "gumdrop 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 90 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 91 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 92 | ] 93 | 94 | [[package]] 95 | name = "cc" 96 | version = "1.0.45" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | 99 | [[package]] 100 | name = "cfg-if" 101 | version = "0.1.10" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | 104 | [[package]] 105 | name = "chrono" 106 | version = "0.4.9" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | dependencies = [ 109 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 114 | ] 115 | 116 | [[package]] 117 | name = "darling" 118 | version = "0.9.0" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | dependencies = [ 121 | "darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 122 | "darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 123 | ] 124 | 125 | [[package]] 126 | name = "darling_core" 127 | version = "0.9.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | dependencies = [ 130 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 131 | "ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 132 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 133 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 134 | "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 135 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 136 | ] 137 | 138 | [[package]] 139 | name = "darling_macro" 140 | version = "0.9.0" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | dependencies = [ 143 | "darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 144 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 145 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 146 | ] 147 | 148 | [[package]] 149 | name = "failure" 150 | version = "0.1.5" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | dependencies = [ 153 | "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", 154 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 155 | ] 156 | 157 | [[package]] 158 | name = "failure_derive" 159 | version = "0.1.5" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | dependencies = [ 162 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 163 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 164 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 165 | "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", 166 | ] 167 | 168 | [[package]] 169 | name = "fnv" 170 | version = "1.0.6" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | 173 | [[package]] 174 | name = "generational-arena" 175 | version = "0.2.3" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | dependencies = [ 178 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 179 | ] 180 | 181 | [[package]] 182 | name = "gumdrop" 183 | version = "0.6.0" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | dependencies = [ 186 | "gumdrop_derive 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 187 | ] 188 | 189 | [[package]] 190 | name = "gumdrop_derive" 191 | version = "0.6.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | dependencies = [ 194 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 195 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 196 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 197 | ] 198 | 199 | [[package]] 200 | name = "ident_case" 201 | version = "1.0.1" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | 204 | [[package]] 205 | name = "lazy_static" 206 | version = "1.4.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | 209 | [[package]] 210 | name = "libc" 211 | version = "0.2.62" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | 214 | [[package]] 215 | name = "log" 216 | version = "0.4.8" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | dependencies = [ 219 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 220 | ] 221 | 222 | [[package]] 223 | name = "memchr" 224 | version = "2.2.1" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | 227 | [[package]] 228 | name = "num-integer" 229 | version = "0.1.41" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | dependencies = [ 232 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 233 | "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 234 | ] 235 | 236 | [[package]] 237 | name = "num-traits" 238 | version = "0.2.8" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | dependencies = [ 241 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 242 | ] 243 | 244 | [[package]] 245 | name = "proc-macro2" 246 | version = "0.4.30" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | dependencies = [ 249 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 250 | ] 251 | 252 | [[package]] 253 | name = "proc-macro2" 254 | version = "1.0.5" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | dependencies = [ 257 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 258 | ] 259 | 260 | [[package]] 261 | name = "quote" 262 | version = "0.6.13" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | dependencies = [ 265 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 266 | ] 267 | 268 | [[package]] 269 | name = "quote" 270 | version = "1.0.2" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | dependencies = [ 273 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 274 | ] 275 | 276 | [[package]] 277 | name = "redox_syscall" 278 | version = "0.1.56" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | 281 | [[package]] 282 | name = "regex" 283 | version = "1.3.1" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | dependencies = [ 286 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", 287 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 288 | "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 289 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 290 | ] 291 | 292 | [[package]] 293 | name = "regex-syntax" 294 | version = "0.6.12" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | 297 | [[package]] 298 | name = "rustc-demangle" 299 | version = "0.1.16" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | 302 | [[package]] 303 | name = "secrecy" 304 | version = "0.2.2" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | dependencies = [ 307 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 308 | "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 309 | ] 310 | 311 | [[package]] 312 | name = "semver" 313 | version = "0.9.0" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | dependencies = [ 316 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 317 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 318 | ] 319 | 320 | [[package]] 321 | name = "semver-parser" 322 | version = "0.7.0" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | 325 | [[package]] 326 | name = "serde" 327 | version = "1.0.101" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | dependencies = [ 330 | "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 331 | ] 332 | 333 | [[package]] 334 | name = "serde_derive" 335 | version = "1.0.101" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | dependencies = [ 338 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 339 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 340 | "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 341 | ] 342 | 343 | [[package]] 344 | name = "signal-hook" 345 | version = "0.1.10" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | dependencies = [ 348 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 349 | "signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 350 | ] 351 | 352 | [[package]] 353 | name = "signal-hook-registry" 354 | version = "1.1.1" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | dependencies = [ 357 | "arc-swap 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 358 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 359 | ] 360 | 361 | [[package]] 362 | name = "strsim" 363 | version = "0.7.0" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | 366 | [[package]] 367 | name = "syn" 368 | version = "0.15.44" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | dependencies = [ 371 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 373 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 374 | ] 375 | 376 | [[package]] 377 | name = "syn" 378 | version = "1.0.5" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | dependencies = [ 381 | "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 382 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 384 | ] 385 | 386 | [[package]] 387 | name = "synstructure" 388 | version = "0.10.2" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | dependencies = [ 391 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 392 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 393 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 394 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 395 | ] 396 | 397 | [[package]] 398 | name = "termcolor" 399 | version = "1.0.5" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | dependencies = [ 402 | "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 403 | ] 404 | 405 | [[package]] 406 | name = "thread_local" 407 | version = "0.3.6" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | dependencies = [ 410 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 411 | ] 412 | 413 | [[package]] 414 | name = "time" 415 | version = "0.1.42" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | dependencies = [ 418 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 419 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 420 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 421 | ] 422 | 423 | [[package]] 424 | name = "toml" 425 | version = "0.5.3" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | dependencies = [ 428 | "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", 429 | ] 430 | 431 | [[package]] 432 | name = "unicode-xid" 433 | version = "0.1.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | 436 | [[package]] 437 | name = "unicode-xid" 438 | version = "0.2.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | 441 | [[package]] 442 | name = "wait-timeout" 443 | version = "0.2.0" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | dependencies = [ 446 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 447 | ] 448 | 449 | [[package]] 450 | name = "winapi" 451 | version = "0.3.8" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | dependencies = [ 454 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 455 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 456 | ] 457 | 458 | [[package]] 459 | name = "winapi-i686-pc-windows-gnu" 460 | version = "0.4.0" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | 463 | [[package]] 464 | name = "winapi-util" 465 | version = "0.1.2" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | dependencies = [ 468 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 469 | ] 470 | 471 | [[package]] 472 | name = "winapi-x86_64-pc-windows-gnu" 473 | version = "0.4.0" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | 476 | [[package]] 477 | name = "wincolor" 478 | version = "1.0.2" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | dependencies = [ 481 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 482 | "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 483 | ] 484 | 485 | [[package]] 486 | name = "zeroize" 487 | version = "0.9.3" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | 490 | [metadata] 491 | "checksum abscissa_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61f2a52e2ac5c37ca7e7b1a07b5861ecf2629499cd569a4eed9ec8d8a3d88064" 492 | "checksum abscissa_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58a070cdc9a26e8e0b594e3968122f509f2a4223c505658a7e0cb04be4b45b58" 493 | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" 494 | "checksum arc-swap 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f1a1eca3195b729bbd64e292ef2f5fff6b1c28504fed762ce2b1013dde4d8e92" 495 | "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" 496 | "checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5" 497 | "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" 498 | "checksum canonical-path 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" 499 | "checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" 500 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 501 | "checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" 502 | "checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6" 503 | "checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c" 504 | "checksum darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1" 505 | "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" 506 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" 507 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 508 | "checksum generational-arena 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "921c3803adaeb9f9639de5149d9f0f9f4b79f00c423915b701db2e02ed80b9ce" 509 | "checksum gumdrop 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a57b4113bb9af093a1cd0b505a44a93103e32e258296d01fa2def3f37c2c7cc" 510 | "checksum gumdrop_derive 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dae5488e2c090f7586e2027e4ea6fcf8c9d83e2ef64d623993a33a0fb811f1f7" 511 | "checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 512 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 513 | "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" 514 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 515 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 516 | "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" 517 | "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" 518 | "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 519 | "checksum proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0" 520 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 521 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 522 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 523 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" 524 | "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" 525 | "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 526 | "checksum secrecy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "69381774972c1fe76bfd9001609fa2b6f97674a1cb6e43bd51d6e9d7d26880c9" 527 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 528 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 529 | "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" 530 | "checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" 531 | "checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68" 532 | "checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc" 533 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" 534 | "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 535 | "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" 536 | "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" 537 | "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" 538 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 539 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" 540 | "checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" 541 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 542 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 543 | "checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 544 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 545 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 546 | "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" 547 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 548 | "checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" 549 | "checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" 550 | -------------------------------------------------------------------------------- /cargo-movemint/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cargo-movemint" 3 | authors = ["LOL"] 4 | version = "0.0.0" 5 | publish = false 6 | edition = "2018" 7 | 8 | [dependencies] 9 | abscissa_core = "0.3.0" 10 | failure = "0.1" 11 | gumdrop = "0.6" 12 | lazy_static = "1" 13 | serde = { version = "1", features = ["serde_derive"] } 14 | 15 | [dev-dependencies.abscissa_core] 16 | version = "0.3.0" 17 | features = ["testing"] 18 | 19 | -------------------------------------------------------------------------------- /cargo-movemint/README.md: -------------------------------------------------------------------------------- 1 | # cargo-movemint 2 | 3 | Cargo plugin for working with [Movemint]. 4 | 5 | The plugin is authored using [Abscissa], a Rust application framework. 6 | 7 | [Movemint]: https://github.com/open-libra/movemint 8 | [Abscissa]: https://github.com/iqlusioninc/abscissa 9 | -------------------------------------------------------------------------------- /cargo-movemint/src/application.rs: -------------------------------------------------------------------------------- 1 | //! CargoMovemint Abscissa Application 2 | 3 | use crate::{commands::CargoMovemintCmd, config::CargoMovemintConfig}; 4 | use abscissa_core::{ 5 | application, config, logging, Application, EntryPoint, FrameworkError, StandardPaths, 6 | }; 7 | use lazy_static::lazy_static; 8 | 9 | lazy_static! { 10 | /// Application state 11 | pub static ref APPLICATION: application::Lock = application::Lock::default(); 12 | } 13 | 14 | /// Obtain a read-only (multi-reader) lock on the application state. 15 | /// 16 | /// Panics if the application state has not been initialized. 17 | pub fn app_reader() -> application::lock::Reader { 18 | APPLICATION.read() 19 | } 20 | 21 | /// Obtain an exclusive mutable lock on the application state. 22 | pub fn app_writer() -> application::lock::Writer { 23 | APPLICATION.write() 24 | } 25 | 26 | /// Obtain a read-only (multi-reader) lock on the application configuration. 27 | /// 28 | /// Panics if the application configuration has not been loaded. 29 | pub fn app_config() -> config::Reader { 30 | config::Reader::new(&APPLICATION) 31 | } 32 | 33 | /// CargoMovemint Application 34 | #[derive(Debug)] 35 | pub struct CargoMovemintApp { 36 | /// Application configuration. 37 | config: Option, 38 | 39 | /// Application state. 40 | state: application::State, 41 | } 42 | 43 | /// Initialize a new application instance. 44 | /// 45 | /// By default no configuration is loaded, and the framework state is 46 | /// initialized to a default, empty state (no components, threads, etc). 47 | impl Default for CargoMovemintApp { 48 | fn default() -> Self { 49 | Self { 50 | config: None, 51 | state: application::State::default(), 52 | } 53 | } 54 | } 55 | 56 | impl Application for CargoMovemintApp { 57 | /// Entrypoint command for this application. 58 | type Cmd = EntryPoint; 59 | 60 | /// Application configuration. 61 | type Cfg = CargoMovemintConfig; 62 | 63 | /// Paths to resources within the application. 64 | type Paths = StandardPaths; 65 | 66 | /// Accessor for application configuration. 67 | fn config(&self) -> &CargoMovemintConfig { 68 | self.config.as_ref().expect("config not loaded") 69 | } 70 | 71 | /// Borrow the application state immutably. 72 | fn state(&self) -> &application::State { 73 | &self.state 74 | } 75 | 76 | /// Borrow the application state mutably. 77 | fn state_mut(&mut self) -> &mut application::State { 78 | &mut self.state 79 | } 80 | 81 | /// Register all components used by this application. 82 | /// 83 | /// If you would like to add additional components to your application 84 | /// beyond the default ones provided by the framework, this is the place 85 | /// to do so. 86 | fn register_components(&mut self, command: &Self::Cmd) -> Result<(), FrameworkError> { 87 | let components = self.framework_components(command)?; 88 | self.state.components.register(components) 89 | } 90 | 91 | /// Post-configuration lifecycle callback. 92 | /// 93 | /// Called regardless of whether config is loaded to indicate this is the 94 | /// time in app lifecycle when configuration would be loaded if 95 | /// possible. 96 | fn after_config(&mut self, config: Self::Cfg) -> Result<(), FrameworkError> { 97 | // Configure components 98 | self.state.components.after_config(&config)?; 99 | self.config = Some(config); 100 | Ok(()) 101 | } 102 | 103 | /// Get logging configuration from command-line options 104 | fn logging_config(&self, command: &EntryPoint) -> logging::Config { 105 | if command.verbose { 106 | logging::Config::verbose() 107 | } else { 108 | logging::Config::default() 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /cargo-movemint/src/bin/cargo-movemint/main.rs: -------------------------------------------------------------------------------- 1 | //! Main entry point for CargoMovemint 2 | 3 | #![deny(warnings, missing_docs, trivial_casts, unused_qualifications)] 4 | #![forbid(unsafe_code)] 5 | 6 | use cargo_movemint::application::APPLICATION; 7 | 8 | /// Boot CargoMovemint 9 | fn main() { 10 | abscissa_core::boot(&APPLICATION); 11 | } 12 | -------------------------------------------------------------------------------- /cargo-movemint/src/commands.rs: -------------------------------------------------------------------------------- 1 | //! CargoMovemint Subcommands 2 | //! 3 | //! This is where you specify the subcommands of your application. 4 | //! 5 | //! The default application comes with two subcommands: 6 | //! 7 | //! - `start`: launches the application 8 | //! - `version`: print application version 9 | //! 10 | //! See the `impl Configurable` below for how to specify the path to the 11 | //! application's configuration file. 12 | 13 | mod start; 14 | mod version; 15 | 16 | use self::{start::StartCmd, version::VersionCmd}; 17 | use crate::config::CargoMovemintConfig; 18 | use abscissa_core::{ 19 | config::Override, Command, Configurable, FrameworkError, Help, Options, Runnable, 20 | }; 21 | use std::path::PathBuf; 22 | 23 | /// CargoMovemint Configuration Filename 24 | pub const CONFIG_FILE: &str = "cargo_movemint.toml"; 25 | 26 | /// CargoMovemint Subcommands 27 | #[derive(Command, Debug, Options, Runnable)] 28 | pub enum CargoMovemintCmd { 29 | /// The `help` subcommand 30 | #[options(help = "get usage information")] 31 | Help(Help), 32 | 33 | /// The `start` subcommand 34 | #[options(help = "start the application")] 35 | Start(StartCmd), 36 | 37 | /// The `version` subcommand 38 | #[options(help = "display version information")] 39 | Version(VersionCmd), 40 | } 41 | 42 | /// This trait allows you to define how application configuration is loaded. 43 | impl Configurable for CargoMovemintCmd { 44 | /// Location of the configuration file 45 | fn config_path(&self) -> Option { 46 | // Check if the config file exists, and if it does not, ignore it. 47 | // If you'd like for a missing configuration file to be a hard error 48 | // instead, always return `Some(CONFIG_FILE)` here. 49 | let filename = PathBuf::from(CONFIG_FILE); 50 | 51 | if filename.exists() { 52 | Some(filename) 53 | } else { 54 | None 55 | } 56 | } 57 | 58 | /// Apply changes to the config after it's been loaded, e.g. overriding 59 | /// values in a config file using command-line options. 60 | /// 61 | /// This can be safely deleted if you don't want to override config 62 | /// settings from command-line options. 63 | fn process_config( 64 | &self, 65 | config: CargoMovemintConfig, 66 | ) -> Result { 67 | match self { 68 | CargoMovemintCmd::Start(cmd) => cmd.override_config(config), 69 | _ => Ok(config), 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /cargo-movemint/src/commands/start.rs: -------------------------------------------------------------------------------- 1 | //! `start` subcommand - example of how to write a subcommand 2 | 3 | /// App-local prelude includes `app_reader()`/`app_writer()`/`app_config()` 4 | /// accessors along with logging macros. Customize as you see fit. 5 | use crate::prelude::*; 6 | 7 | use crate::config::CargoMovemintConfig; 8 | use abscissa_core::{config, Command, FrameworkError, Options, Runnable}; 9 | 10 | /// `start` subcommand 11 | /// 12 | /// The `Options` proc macro generates an option parser based on the struct 13 | /// definition, and is defined in the `gumdrop` crate. See their documentation 14 | /// for a more comprehensive example: 15 | /// 16 | /// 17 | #[derive(Command, Debug, Options)] 18 | pub struct StartCmd { 19 | /// To whom are we saying hello? 20 | #[options(free)] 21 | recipient: Vec, 22 | } 23 | 24 | impl Runnable for StartCmd { 25 | /// Start the application. 26 | fn run(&self) { 27 | let config = app_config(); 28 | println!("Hello, {}!", &config.hello.recipient); 29 | } 30 | } 31 | 32 | impl config::Override for StartCmd { 33 | // Process the given command line options, overriding settings from 34 | // a configuration file using explicit flags taken from command-line 35 | // arguments. 36 | fn override_config( 37 | &self, 38 | mut config: CargoMovemintConfig, 39 | ) -> Result { 40 | if !self.recipient.is_empty() { 41 | config.hello.recipient = self.recipient.join(" "); 42 | } 43 | 44 | Ok(config) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /cargo-movemint/src/commands/version.rs: -------------------------------------------------------------------------------- 1 | //! `version` subcommand 2 | 3 | #![allow(clippy::never_loop)] 4 | 5 | use super::CargoMovemintCmd; 6 | use abscissa_core::{Command, Options, Runnable}; 7 | 8 | /// `version` subcommand 9 | #[derive(Command, Debug, Default, Options)] 10 | pub struct VersionCmd {} 11 | 12 | impl Runnable for VersionCmd { 13 | /// Print version message 14 | fn run(&self) { 15 | println!( 16 | "{} {}", 17 | CargoMovemintCmd::name(), 18 | CargoMovemintCmd::version() 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /cargo-movemint/src/config.rs: -------------------------------------------------------------------------------- 1 | //! CargoMovemint Config 2 | //! 3 | //! See instructions in `commands.rs` to specify the path to your 4 | //! application's configuration file and/or command-line options 5 | //! for specifying it. 6 | 7 | use abscissa_core::Config; 8 | use serde::{Deserialize, Serialize}; 9 | 10 | /// CargoMovemint Configuration 11 | #[derive(Clone, Config, Debug, Deserialize, Serialize)] 12 | #[serde(deny_unknown_fields)] 13 | pub struct CargoMovemintConfig { 14 | /// An example configuration section 15 | pub hello: ExampleSection, 16 | } 17 | 18 | /// Default configuration settings. 19 | /// 20 | /// Note: if your needs are as simple as below, you can 21 | /// use `#[derive(Default)]` on CargoMovemintConfig instead. 22 | impl Default for CargoMovemintConfig { 23 | fn default() -> Self { 24 | Self { 25 | hello: ExampleSection::default(), 26 | } 27 | } 28 | } 29 | 30 | /// Example configuration section. 31 | /// 32 | /// Delete this and replace it with your actual configuration structs. 33 | #[derive(Clone, Debug, Deserialize, Serialize)] 34 | #[serde(deny_unknown_fields)] 35 | pub struct ExampleSection { 36 | /// Example configuration value 37 | pub recipient: String, 38 | } 39 | 40 | impl Default for ExampleSection { 41 | fn default() -> Self { 42 | Self { 43 | recipient: "world".to_owned(), 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /cargo-movemint/src/error.rs: -------------------------------------------------------------------------------- 1 | //! Error types 2 | 3 | use abscissa_core::err; 4 | use failure::Fail; 5 | use std::{fmt, io}; 6 | 7 | /// Error type 8 | #[derive(Debug)] 9 | pub struct Error(abscissa_core::Error); 10 | 11 | /// Kinds of errors 12 | #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)] 13 | pub enum ErrorKind { 14 | /// Error in configuration file 15 | #[fail(display = "config error")] 16 | Config, 17 | 18 | /// Input/output error 19 | #[fail(display = "I/O error")] 20 | Io, 21 | } 22 | 23 | impl fmt::Display for Error { 24 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 25 | self.0.fmt(f) 26 | } 27 | } 28 | 29 | impl From> for Error { 30 | fn from(other: abscissa_core::Error) -> Self { 31 | Error(other) 32 | } 33 | } 34 | 35 | impl From for Error { 36 | fn from(other: io::Error) -> Self { 37 | err!(ErrorKind::Io, other).into() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /cargo-movemint/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! CargoMovemint 2 | //! 3 | //! Application based on the [Abscissa] framework. 4 | //! 5 | //! [Abscissa]: https://github.com/iqlusioninc/abscissa 6 | 7 | #![deny(warnings, missing_docs, trivial_casts, unused_qualifications)] 8 | #![forbid(unsafe_code)] 9 | 10 | pub mod application; 11 | pub mod commands; 12 | pub mod config; 13 | pub mod error; 14 | pub mod prelude; 15 | -------------------------------------------------------------------------------- /cargo-movemint/src/prelude.rs: -------------------------------------------------------------------------------- 1 | //! Application-local prelude: conveniently import types/functions/macros 2 | //! which are generally useful and should be available everywhere. 3 | 4 | /// Application state accessors 5 | pub use crate::application::{app_config, app_reader, app_writer}; 6 | 7 | /// Commonly used Abscissa traits 8 | pub use abscissa_core::{Application, Command, Runnable}; 9 | 10 | /// Logging macros 11 | pub use abscissa_core::log::{debug, error, info, log, log_enabled, trace, warn}; 12 | -------------------------------------------------------------------------------- /cargo-movemint/tests/acceptance.rs: -------------------------------------------------------------------------------- 1 | //! Acceptance test: runs the application as a subprocess and asserts its 2 | //! output for given argument combinations matches what is expected. 3 | //! 4 | //! Modify and/or delete these as you see fit to test the specific needs of 5 | //! your application. 6 | //! 7 | //! For more information, see: 8 | //! 9 | 10 | #![deny(warnings, missing_docs, trivial_casts, unused_qualifications)] 11 | #![forbid(unsafe_code)] 12 | 13 | use abscissa_core::testing::prelude::*; 14 | use cargo_movemint::config::CargoMovemintConfig; 15 | use lazy_static::lazy_static; 16 | 17 | lazy_static! { 18 | /// Executes your application binary via `cargo run`. 19 | /// 20 | /// Storing this value in a `lazy_static!` ensures that all instances of 21 | /// the runner acquire a mutex when executing commands and inspecting 22 | /// exit statuses, serializing what would otherwise be multithreaded 23 | /// invocations as `cargo test` executes tests in parallel by default. 24 | pub static ref RUNNER: CmdRunner = CmdRunner::default(); 25 | } 26 | 27 | /// Use `CargoMovemintConfig::default()` value if no config or args 28 | #[test] 29 | fn start_no_args() { 30 | let mut runner = RUNNER.clone(); 31 | let mut cmd = runner.arg("start").capture_stdout().run(); 32 | cmd.stdout().expect_line("Hello, world!"); 33 | cmd.wait().unwrap().expect_success(); 34 | } 35 | 36 | /// Use command-line argument value 37 | #[test] 38 | fn start_with_args() { 39 | let mut runner = RUNNER.clone(); 40 | let mut cmd = runner 41 | .args(&["start", "acceptance", "test"]) 42 | .capture_stdout() 43 | .run(); 44 | 45 | cmd.stdout().expect_line("Hello, acceptance test!"); 46 | cmd.wait().unwrap().expect_success(); 47 | } 48 | 49 | /// Use configured value 50 | #[test] 51 | fn start_with_config_no_args() { 52 | let mut config = CargoMovemintConfig::default(); 53 | config.hello.recipient = "configured recipient".to_owned(); 54 | let expected_line = format!("Hello, {}!", &config.hello.recipient); 55 | 56 | let mut runner = RUNNER.clone(); 57 | let mut cmd = runner.config(&config).arg("start").capture_stdout().run(); 58 | cmd.stdout().expect_line(&expected_line); 59 | cmd.wait().unwrap().expect_success(); 60 | } 61 | 62 | /// Override configured value with command-line argument 63 | #[test] 64 | fn start_with_config_and_args() { 65 | let mut config = CargoMovemintConfig::default(); 66 | config.hello.recipient = "configured recipient".to_owned(); 67 | 68 | let mut runner = RUNNER.clone(); 69 | let mut cmd = runner 70 | .config(&config) 71 | .args(&["start", "acceptance", "test"]) 72 | .capture_stdout() 73 | .run(); 74 | 75 | cmd.stdout().expect_line("Hello, acceptance test!"); 76 | cmd.wait().unwrap().expect_success(); 77 | } 78 | 79 | /// Example of a test which matches a regular expression 80 | #[test] 81 | fn version_no_args() { 82 | let mut runner = RUNNER.clone(); 83 | let mut cmd = runner.arg("version").capture_stdout().run(); 84 | cmd.stdout().expect_regex(r"\A\w+ [\d\.\-]+\z"); 85 | } 86 | -------------------------------------------------------------------------------- /docs/Components.md: -------------------------------------------------------------------------------- 1 | Learn more about [Abscissa]'s ECS-like design. This is a framework we plan to use and improve upon. 2 | 3 | `movemint` will feature the following commands / components: 4 | 5 | - Node 6 | - REPL 7 | - Compiler 8 | - Verifier 9 | - Wallet 10 | 11 | Some of these components will be re-used / shared within the `cargo-move` and `cargo-movemint` tools, which are geared towards researchers and developers whereas `movemint` is (when production-ready) meant for node operators. 12 | 13 | We expect `cargo-move` to be used in Rust-Move work (say by PL researchers, vulnerabilty researchers, etc.) 14 | 15 | We expect `cargo-movemint` to drive a movemint node for development purposes, as well as connecting with Trillian-backed Move repos in the future. 16 | 17 | 18 | [Abscissa]: https://github.com/iqlusioninc/abscissa 19 | -------------------------------------------------------------------------------- /docs/GitStrategy.md: -------------------------------------------------------------------------------- 1 | Libra Core is a fast evolving codebase. Furthermore crates like the Move language `vm` are not readily available as dependable libraries. 2 | 3 | So for now we have a simple approach to make use of Libra Core: using a git submodule. The strategy is likely to change in the near future as we find better ways to deal with this challenge. 4 | 5 | upstream (Libra Core) 6 | 7 | local (your local machine) 8 | 9 | remote (your GitHub-hosted repo) 10 | 11 | downstream (the movemint repo) 12 | 13 | ----- 14 | 15 | TODO: 16 | 17 | git flow 18 | ci / cd / devops 19 | reproducible builds -------------------------------------------------------------------------------- /docs/L_OL_∆.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/docs/L_OL_∆.png -------------------------------------------------------------------------------- /docs/Roadmap.md: -------------------------------------------------------------------------------- 1 | TODO -------------------------------------------------------------------------------- /docs/TCB.md: -------------------------------------------------------------------------------- 1 | TODO -------------------------------------------------------------------------------- /docs/crev.md: -------------------------------------------------------------------------------- 1 | TODO: [cargo-crev] infrastructure for code review 2 | 3 | [cargo-crev]: https://github.com/crev-dev/cargo-crev -------------------------------------------------------------------------------- /docs/tlog-rust-move.md: -------------------------------------------------------------------------------- 1 | # Transparency Logs 2 | 3 | Golang recently got code transparency (see [Go-tlog], [tlog]). 4 | 5 | (Note that Trillian is itself implemented in Golang.) 6 | 7 | # Rust 8 | 9 | A [Rust API for Trillian] will be nice to have. Once we have that we can secure the Rust/crates.io ecosystem better. 10 | 11 | We're planning to build this API ourselves even though it's not in our immediate roadmap. Want to contribute? Contact us on [Discord]! 12 | 13 | # Move 14 | 15 | Wouldn't it be nice to have [Transparency logs for All PLs]? We believe Move should have it too. ∆ 16 | 17 | Once the LC authors deliver on their [plan] of a *versioning scheme for Move*, we may integrate it with our ongoing work on `cargo-move` and `cargo-movemint`. 18 | 19 | [tlog]: https://research.swtch.com/tlog 20 | [Rust API for Trillian]: https://twitter.com/BenLaurie/status/1167335026507337730 21 | [Go-tlog]: https://twitter.com/FiloSottile/status/1167156608545280005 22 | [Transparency logs for All PLs]: https://twitter.com/NaolDuga/status/1167242664028381185 23 | [plan]: https://developers.libra.org/blog/2019/06/18/the-path-forward 24 | [Discord]: https://discord.gg/wXHHxD 25 | -------------------------------------------------------------------------------- /protofiles/abci/abci.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package abci; 3 | 4 | // For more information on gogo.proto, see: 5 | // https://github.com/gogo/protobuf/blob/master/extensions.md 6 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 7 | import "github.com/tendermint/tendermint/crypto/merkle/merkle.proto"; 8 | import "github.com/tendermint/tendermint/libs/common/types.proto"; 9 | import "google/protobuf/timestamp.proto"; 10 | 11 | // This file is copied from http://github.com/tendermint/abci 12 | // NOTE: When using custom types, mind the warnings. 13 | // https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues 14 | 15 | option (gogoproto.marshaler_all) = true; 16 | option (gogoproto.unmarshaler_all) = true; 17 | option (gogoproto.sizer_all) = true; 18 | option (gogoproto.goproto_registration) = true; 19 | // Generate tests 20 | option (gogoproto.populate_all) = true; 21 | option (gogoproto.equal_all) = true; 22 | option (gogoproto.testgen_all) = true; 23 | 24 | //---------------------------------------- 25 | // Request types 26 | 27 | message Request { 28 | oneof value { 29 | RequestEcho echo = 2; 30 | RequestFlush flush = 3; 31 | RequestInfo info = 4; 32 | RequestSetOption set_option = 5; 33 | RequestInitChain init_chain = 6; 34 | RequestQuery query = 7; 35 | RequestBeginBlock begin_block = 8; 36 | RequestCheckTx check_tx = 9; 37 | RequestDeliverTx deliver_tx = 19; 38 | RequestEndBlock end_block = 11; 39 | RequestCommit commit = 12; 40 | } 41 | } 42 | 43 | message RequestEcho { 44 | string message = 1; 45 | } 46 | 47 | message RequestFlush { 48 | } 49 | 50 | message RequestInfo { 51 | string version = 1; 52 | uint64 block_version = 2; 53 | uint64 p2p_version = 3; 54 | } 55 | 56 | // nondeterministic 57 | message RequestSetOption { 58 | string key = 1; 59 | string value = 2; 60 | } 61 | 62 | message RequestInitChain { 63 | google.protobuf.Timestamp time = 1 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true]; 64 | string chain_id = 2; 65 | ConsensusParams consensus_params = 3; 66 | repeated ValidatorUpdate validators = 4 [(gogoproto.nullable)=false]; 67 | bytes app_state_bytes = 5; 68 | } 69 | 70 | message RequestQuery { 71 | bytes data = 1; 72 | string path = 2; 73 | int64 height = 3; 74 | bool prove = 4; 75 | } 76 | 77 | message RequestBeginBlock { 78 | bytes hash = 1; 79 | Header header = 2 [(gogoproto.nullable)=false]; 80 | LastCommitInfo last_commit_info = 3 [(gogoproto.nullable)=false]; 81 | repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; 82 | } 83 | 84 | message RequestCheckTx { 85 | bytes tx = 1; 86 | } 87 | 88 | message RequestDeliverTx { 89 | bytes tx = 1; 90 | } 91 | 92 | message RequestEndBlock { 93 | int64 height = 1; 94 | } 95 | 96 | message RequestCommit { 97 | } 98 | 99 | //---------------------------------------- 100 | // Response types 101 | 102 | message Response { 103 | oneof value { 104 | ResponseException exception = 1; 105 | ResponseEcho echo = 2; 106 | ResponseFlush flush = 3; 107 | ResponseInfo info = 4; 108 | ResponseSetOption set_option = 5; 109 | ResponseInitChain init_chain = 6; 110 | ResponseQuery query = 7; 111 | ResponseBeginBlock begin_block = 8; 112 | ResponseCheckTx check_tx = 9; 113 | ResponseDeliverTx deliver_tx = 10; 114 | ResponseEndBlock end_block = 11; 115 | ResponseCommit commit = 12; 116 | } 117 | } 118 | 119 | // nondeterministic 120 | message ResponseException { 121 | string error = 1; 122 | } 123 | 124 | message ResponseEcho { 125 | string message = 1; 126 | } 127 | 128 | message ResponseFlush { 129 | } 130 | 131 | message ResponseInfo { 132 | string data = 1; 133 | 134 | string version = 2; 135 | uint64 app_version = 3; 136 | 137 | int64 last_block_height = 4; 138 | bytes last_block_app_hash = 5; 139 | } 140 | 141 | // nondeterministic 142 | message ResponseSetOption { 143 | uint32 code = 1; 144 | // bytes data = 2; 145 | string log = 3; 146 | string info = 4; 147 | } 148 | 149 | message ResponseInitChain { 150 | ConsensusParams consensus_params = 1; 151 | repeated ValidatorUpdate validators = 2 [(gogoproto.nullable)=false]; 152 | } 153 | 154 | message ResponseQuery { 155 | uint32 code = 1; 156 | // bytes data = 2; // use "value" instead. 157 | string log = 3; // nondeterministic 158 | string info = 4; // nondeterministic 159 | int64 index = 5; 160 | bytes key = 6; 161 | bytes value = 7; 162 | merkle.Proof proof = 8; 163 | int64 height = 9; 164 | string codespace = 10; 165 | } 166 | 167 | message ResponseBeginBlock { 168 | repeated Event events = 1 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 169 | } 170 | 171 | message ResponseCheckTx { 172 | uint32 code = 1; 173 | bytes data = 2; 174 | string log = 3; // nondeterministic 175 | string info = 4; // nondeterministic 176 | int64 gas_wanted = 5; 177 | int64 gas_used = 6; 178 | repeated Event events = 7 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 179 | string codespace = 8; 180 | } 181 | 182 | message ResponseDeliverTx { 183 | uint32 code = 1; 184 | bytes data = 2; 185 | string log = 3; // nondeterministic 186 | string info = 4; // nondeterministic 187 | int64 gas_wanted = 5; 188 | int64 gas_used = 6; 189 | repeated Event events = 7 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 190 | string codespace = 8; 191 | } 192 | 193 | message ResponseEndBlock { 194 | repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable)=false]; 195 | ConsensusParams consensus_param_updates = 2; 196 | repeated Event events = 3 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 197 | } 198 | 199 | message ResponseCommit { 200 | // reserve 1 201 | bytes data = 2; 202 | } 203 | 204 | //---------------------------------------- 205 | // Misc. 206 | 207 | // ConsensusParams contains all consensus-relevant parameters 208 | // that can be adjusted by the abci app 209 | message ConsensusParams { 210 | BlockParams block = 1; 211 | EvidenceParams evidence = 2; 212 | ValidatorParams validator = 3; 213 | } 214 | 215 | // BlockParams contains limits on the block size. 216 | message BlockParams { 217 | // Note: must be greater than 0 218 | int64 max_bytes = 1; 219 | // Note: must be greater or equal to -1 220 | int64 max_gas = 2; 221 | } 222 | 223 | // EvidenceParams contains limits on the evidence. 224 | message EvidenceParams { 225 | // Note: must be greater than 0 226 | int64 max_age = 1; 227 | } 228 | 229 | // ValidatorParams contains limits on validators. 230 | message ValidatorParams { 231 | repeated string pub_key_types = 1; 232 | } 233 | 234 | message LastCommitInfo { 235 | int32 round = 1; 236 | repeated VoteInfo votes = 2 [(gogoproto.nullable)=false]; 237 | } 238 | 239 | message Event { 240 | string type = 1; 241 | repeated common.KVPair attributes = 2 [(gogoproto.nullable)=false, (gogoproto.jsontag)="attributes,omitempty"]; 242 | } 243 | 244 | //---------------------------------------- 245 | // Blockchain Types 246 | 247 | message Header { 248 | // basic block info 249 | Version version = 1 [(gogoproto.nullable)=false]; 250 | string chain_id = 2 [(gogoproto.customname)="ChainID"]; 251 | int64 height = 3; 252 | google.protobuf.Timestamp time = 4 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true]; 253 | int64 num_txs = 5; 254 | int64 total_txs = 6; 255 | 256 | // prev block info 257 | BlockID last_block_id = 7 [(gogoproto.nullable)=false]; 258 | 259 | // hashes of block data 260 | bytes last_commit_hash = 8; // commit from validators from the last block 261 | bytes data_hash = 9; // transactions 262 | 263 | // hashes from the app output from the prev block 264 | bytes validators_hash = 10; // validators for the current block 265 | bytes next_validators_hash = 11; // validators for the next block 266 | bytes consensus_hash = 12; // consensus params for current block 267 | bytes app_hash = 13; // state after txs from the previous block 268 | bytes last_results_hash = 14;// root hash of all results from the txs from the previous block 269 | 270 | // consensus info 271 | bytes evidence_hash = 15; // evidence included in the block 272 | bytes proposer_address = 16; // original proposer of the block 273 | } 274 | 275 | message Version { 276 | uint64 Block = 1; 277 | uint64 App = 2; 278 | } 279 | 280 | 281 | message BlockID { 282 | bytes hash = 1; 283 | PartSetHeader parts_header = 2 [(gogoproto.nullable)=false]; 284 | } 285 | 286 | message PartSetHeader { 287 | int32 total = 1; 288 | bytes hash = 2; 289 | } 290 | 291 | // Validator 292 | message Validator { 293 | bytes address = 1; 294 | //PubKey pub_key = 2 [(gogoproto.nullable)=false]; 295 | int64 power = 3; 296 | } 297 | 298 | // ValidatorUpdate 299 | message ValidatorUpdate { 300 | PubKey pub_key = 1 [(gogoproto.nullable)=false]; 301 | int64 power = 2; 302 | } 303 | 304 | // VoteInfo 305 | message VoteInfo { 306 | Validator validator = 1 [(gogoproto.nullable)=false]; 307 | bool signed_last_block = 2; 308 | } 309 | 310 | message PubKey { 311 | string type = 1; 312 | bytes data = 2; 313 | } 314 | 315 | message Evidence { 316 | string type = 1; 317 | Validator validator = 2 [(gogoproto.nullable)=false]; 318 | int64 height = 3; 319 | google.protobuf.Timestamp time = 4 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true]; 320 | int64 total_voting_power = 5; 321 | } 322 | 323 | //---------------------------------------- 324 | // Service Definition 325 | 326 | service ABCIApplication { 327 | rpc Echo(RequestEcho) returns (ResponseEcho) ; 328 | rpc Flush(RequestFlush) returns (ResponseFlush); 329 | rpc Info(RequestInfo) returns (ResponseInfo); 330 | rpc SetOption(RequestSetOption) returns (ResponseSetOption); 331 | rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); 332 | rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); 333 | rpc Query(RequestQuery) returns (ResponseQuery); 334 | rpc Commit(RequestCommit) returns (ResponseCommit); 335 | rpc InitChain(RequestInitChain) returns (ResponseInitChain); 336 | rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); 337 | rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); 338 | } 339 | -------------------------------------------------------------------------------- /protofiles/abci/github.com/gogo/protobuf/gogoproto/gogo.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers for Go with Gadgets 2 | // 3 | // Copyright (c) 2013, The GoGo Authors. All rights reserved. 4 | // http://github.com/gogo/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | syntax = "proto2"; 30 | package gogoproto; 31 | 32 | import "google/protobuf/descriptor.proto"; 33 | 34 | option java_package = "com.google.protobuf"; 35 | option java_outer_classname = "GoGoProtos"; 36 | option go_package = "github.com/gogo/protobuf/gogoproto"; 37 | 38 | extend google.protobuf.EnumOptions { 39 | optional bool goproto_enum_prefix = 62001; 40 | optional bool goproto_enum_stringer = 62021; 41 | optional bool enum_stringer = 62022; 42 | optional string enum_customname = 62023; 43 | optional bool enumdecl = 62024; 44 | } 45 | 46 | extend google.protobuf.EnumValueOptions { 47 | optional string enumvalue_customname = 66001; 48 | } 49 | 50 | extend google.protobuf.FileOptions { 51 | optional bool goproto_getters_all = 63001; 52 | optional bool goproto_enum_prefix_all = 63002; 53 | optional bool goproto_stringer_all = 63003; 54 | optional bool verbose_equal_all = 63004; 55 | optional bool face_all = 63005; 56 | optional bool gostring_all = 63006; 57 | optional bool populate_all = 63007; 58 | optional bool stringer_all = 63008; 59 | optional bool onlyone_all = 63009; 60 | 61 | optional bool equal_all = 63013; 62 | optional bool description_all = 63014; 63 | optional bool testgen_all = 63015; 64 | optional bool benchgen_all = 63016; 65 | optional bool marshaler_all = 63017; 66 | optional bool unmarshaler_all = 63018; 67 | optional bool stable_marshaler_all = 63019; 68 | 69 | optional bool sizer_all = 63020; 70 | 71 | optional bool goproto_enum_stringer_all = 63021; 72 | optional bool enum_stringer_all = 63022; 73 | 74 | optional bool unsafe_marshaler_all = 63023; 75 | optional bool unsafe_unmarshaler_all = 63024; 76 | 77 | optional bool goproto_extensions_map_all = 63025; 78 | optional bool goproto_unrecognized_all = 63026; 79 | optional bool gogoproto_import = 63027; 80 | optional bool protosizer_all = 63028; 81 | optional bool compare_all = 63029; 82 | optional bool typedecl_all = 63030; 83 | optional bool enumdecl_all = 63031; 84 | 85 | optional bool goproto_registration = 63032; 86 | optional bool messagename_all = 63033; 87 | 88 | optional bool goproto_sizecache_all = 63034; 89 | optional bool goproto_unkeyed_all = 63035; 90 | } 91 | 92 | extend google.protobuf.MessageOptions { 93 | optional bool goproto_getters = 64001; 94 | optional bool goproto_stringer = 64003; 95 | optional bool verbose_equal = 64004; 96 | optional bool face = 64005; 97 | optional bool gostring = 64006; 98 | optional bool populate = 64007; 99 | optional bool stringer = 67008; 100 | optional bool onlyone = 64009; 101 | 102 | optional bool equal = 64013; 103 | optional bool description = 64014; 104 | optional bool testgen = 64015; 105 | optional bool benchgen = 64016; 106 | optional bool marshaler = 64017; 107 | optional bool unmarshaler = 64018; 108 | optional bool stable_marshaler = 64019; 109 | 110 | optional bool sizer = 64020; 111 | 112 | optional bool unsafe_marshaler = 64023; 113 | optional bool unsafe_unmarshaler = 64024; 114 | 115 | optional bool goproto_extensions_map = 64025; 116 | optional bool goproto_unrecognized = 64026; 117 | 118 | optional bool protosizer = 64028; 119 | optional bool compare = 64029; 120 | 121 | optional bool typedecl = 64030; 122 | 123 | optional bool messagename = 64033; 124 | 125 | optional bool goproto_sizecache = 64034; 126 | optional bool goproto_unkeyed = 64035; 127 | } 128 | 129 | extend google.protobuf.FieldOptions { 130 | optional bool nullable = 65001; 131 | optional bool embed = 65002; 132 | optional string customtype = 65003; 133 | optional string customname = 65004; 134 | optional string jsontag = 65005; 135 | optional string moretags = 65006; 136 | optional string casttype = 65007; 137 | optional string castkey = 65008; 138 | optional string castvalue = 65009; 139 | 140 | optional bool stdtime = 65010; 141 | optional bool stdduration = 65011; 142 | optional bool wktpointer = 65012; 143 | 144 | } 145 | -------------------------------------------------------------------------------- /protofiles/abci/github.com/tendermint/tendermint/abci/types/types.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package types; 3 | 4 | // For more information on gogo.proto, see: 5 | // https://github.com/gogo/protobuf/blob/master/extensions.md 6 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 7 | import "github.com/tendermint/tendermint/crypto/merkle/merkle.proto"; 8 | import "github.com/tendermint/tendermint/libs/common/types.proto"; 9 | import "google/protobuf/timestamp.proto"; 10 | 11 | // This file is copied from http://github.com/tendermint/abci 12 | // NOTE: When using custom types, mind the warnings. 13 | // https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues 14 | 15 | option (gogoproto.marshaler_all) = true; 16 | option (gogoproto.unmarshaler_all) = true; 17 | option (gogoproto.sizer_all) = true; 18 | option (gogoproto.goproto_registration) = true; 19 | // Generate tests 20 | option (gogoproto.populate_all) = true; 21 | option (gogoproto.equal_all) = true; 22 | option (gogoproto.testgen_all) = true; 23 | 24 | //---------------------------------------- 25 | // Request types 26 | 27 | message Request { 28 | oneof value { 29 | RequestEcho echo = 2; 30 | RequestFlush flush = 3; 31 | RequestInfo info = 4; 32 | RequestSetOption set_option = 5; 33 | RequestInitChain init_chain = 6; 34 | RequestQuery query = 7; 35 | RequestBeginBlock begin_block = 8; 36 | RequestCheckTx check_tx = 9; 37 | RequestDeliverTx deliver_tx = 19; 38 | RequestEndBlock end_block = 11; 39 | RequestCommit commit = 12; 40 | } 41 | } 42 | 43 | message RequestEcho { 44 | string message = 1; 45 | } 46 | 47 | message RequestFlush { 48 | } 49 | 50 | message RequestInfo { 51 | string version = 1; 52 | uint64 block_version = 2; 53 | uint64 p2p_version = 3; 54 | } 55 | 56 | // nondeterministic 57 | message RequestSetOption { 58 | string key = 1; 59 | string value = 2; 60 | } 61 | 62 | message RequestInitChain { 63 | google.protobuf.Timestamp time = 1 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true]; 64 | string chain_id = 2; 65 | ConsensusParams consensus_params = 3; 66 | repeated ValidatorUpdate validators = 4 [(gogoproto.nullable)=false]; 67 | bytes app_state_bytes = 5; 68 | } 69 | 70 | message RequestQuery { 71 | bytes data = 1; 72 | string path = 2; 73 | int64 height = 3; 74 | bool prove = 4; 75 | } 76 | 77 | message RequestBeginBlock { 78 | bytes hash = 1; 79 | Header header = 2 [(gogoproto.nullable)=false]; 80 | LastCommitInfo last_commit_info = 3 [(gogoproto.nullable)=false]; 81 | repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; 82 | } 83 | 84 | message RequestCheckTx { 85 | bytes tx = 1; 86 | } 87 | 88 | message RequestDeliverTx { 89 | bytes tx = 1; 90 | } 91 | 92 | message RequestEndBlock { 93 | int64 height = 1; 94 | } 95 | 96 | message RequestCommit { 97 | } 98 | 99 | //---------------------------------------- 100 | // Response types 101 | 102 | message Response { 103 | oneof value { 104 | ResponseException exception = 1; 105 | ResponseEcho echo = 2; 106 | ResponseFlush flush = 3; 107 | ResponseInfo info = 4; 108 | ResponseSetOption set_option = 5; 109 | ResponseInitChain init_chain = 6; 110 | ResponseQuery query = 7; 111 | ResponseBeginBlock begin_block = 8; 112 | ResponseCheckTx check_tx = 9; 113 | ResponseDeliverTx deliver_tx = 10; 114 | ResponseEndBlock end_block = 11; 115 | ResponseCommit commit = 12; 116 | } 117 | } 118 | 119 | // nondeterministic 120 | message ResponseException { 121 | string error = 1; 122 | } 123 | 124 | message ResponseEcho { 125 | string message = 1; 126 | } 127 | 128 | message ResponseFlush { 129 | } 130 | 131 | message ResponseInfo { 132 | string data = 1; 133 | 134 | string version = 2; 135 | uint64 app_version = 3; 136 | 137 | int64 last_block_height = 4; 138 | bytes last_block_app_hash = 5; 139 | } 140 | 141 | // nondeterministic 142 | message ResponseSetOption { 143 | uint32 code = 1; 144 | // bytes data = 2; 145 | string log = 3; 146 | string info = 4; 147 | } 148 | 149 | message ResponseInitChain { 150 | ConsensusParams consensus_params = 1; 151 | repeated ValidatorUpdate validators = 2 [(gogoproto.nullable)=false]; 152 | } 153 | 154 | message ResponseQuery { 155 | uint32 code = 1; 156 | // bytes data = 2; // use "value" instead. 157 | string log = 3; // nondeterministic 158 | string info = 4; // nondeterministic 159 | int64 index = 5; 160 | bytes key = 6; 161 | bytes value = 7; 162 | merkle.Proof proof = 8; 163 | int64 height = 9; 164 | string codespace = 10; 165 | } 166 | 167 | message ResponseBeginBlock { 168 | repeated Event events = 1 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 169 | } 170 | 171 | message ResponseCheckTx { 172 | uint32 code = 1; 173 | bytes data = 2; 174 | string log = 3; // nondeterministic 175 | string info = 4; // nondeterministic 176 | int64 gas_wanted = 5; 177 | int64 gas_used = 6; 178 | repeated Event events = 7 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 179 | string codespace = 8; 180 | } 181 | 182 | message ResponseDeliverTx { 183 | uint32 code = 1; 184 | bytes data = 2; 185 | string log = 3; // nondeterministic 186 | string info = 4; // nondeterministic 187 | int64 gas_wanted = 5; 188 | int64 gas_used = 6; 189 | repeated Event events = 7 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 190 | string codespace = 8; 191 | } 192 | 193 | message ResponseEndBlock { 194 | repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable)=false]; 195 | ConsensusParams consensus_param_updates = 2; 196 | repeated Event events = 3 [(gogoproto.nullable)=false, (gogoproto.jsontag)="events,omitempty"]; 197 | } 198 | 199 | message ResponseCommit { 200 | // reserve 1 201 | bytes data = 2; 202 | } 203 | 204 | //---------------------------------------- 205 | // Misc. 206 | 207 | // ConsensusParams contains all consensus-relevant parameters 208 | // that can be adjusted by the abci app 209 | message ConsensusParams { 210 | BlockParams block = 1; 211 | EvidenceParams evidence = 2; 212 | ValidatorParams validator = 3; 213 | } 214 | 215 | // BlockParams contains limits on the block size. 216 | message BlockParams { 217 | // Note: must be greater than 0 218 | int64 max_bytes = 1; 219 | // Note: must be greater or equal to -1 220 | int64 max_gas = 2; 221 | } 222 | 223 | // EvidenceParams contains limits on the evidence. 224 | message EvidenceParams { 225 | // Note: must be greater than 0 226 | int64 max_age = 1; 227 | } 228 | 229 | // ValidatorParams contains limits on validators. 230 | message ValidatorParams { 231 | repeated string pub_key_types = 1; 232 | } 233 | 234 | message LastCommitInfo { 235 | int32 round = 1; 236 | repeated VoteInfo votes = 2 [(gogoproto.nullable)=false]; 237 | } 238 | 239 | message Event { 240 | string type = 1; 241 | repeated common.KVPair attributes = 2 [(gogoproto.nullable)=false, (gogoproto.jsontag)="attributes,omitempty"]; 242 | } 243 | 244 | //---------------------------------------- 245 | // Blockchain Types 246 | 247 | message Header { 248 | // basic block info 249 | Version version = 1 [(gogoproto.nullable)=false]; 250 | string chain_id = 2 [(gogoproto.customname)="ChainID"]; 251 | int64 height = 3; 252 | google.protobuf.Timestamp time = 4 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true]; 253 | int64 num_txs = 5; 254 | int64 total_txs = 6; 255 | 256 | // prev block info 257 | BlockID last_block_id = 7 [(gogoproto.nullable)=false]; 258 | 259 | // hashes of block data 260 | bytes last_commit_hash = 8; // commit from validators from the last block 261 | bytes data_hash = 9; // transactions 262 | 263 | // hashes from the app output from the prev block 264 | bytes validators_hash = 10; // validators for the current block 265 | bytes next_validators_hash = 11; // validators for the next block 266 | bytes consensus_hash = 12; // consensus params for current block 267 | bytes app_hash = 13; // state after txs from the previous block 268 | bytes last_results_hash = 14;// root hash of all results from the txs from the previous block 269 | 270 | // consensus info 271 | bytes evidence_hash = 15; // evidence included in the block 272 | bytes proposer_address = 16; // original proposer of the block 273 | } 274 | 275 | message Version { 276 | uint64 Block = 1; 277 | uint64 App = 2; 278 | } 279 | 280 | 281 | message BlockID { 282 | bytes hash = 1; 283 | PartSetHeader parts_header = 2 [(gogoproto.nullable)=false]; 284 | } 285 | 286 | message PartSetHeader { 287 | int32 total = 1; 288 | bytes hash = 2; 289 | } 290 | 291 | // Validator 292 | message Validator { 293 | bytes address = 1; 294 | //PubKey pub_key = 2 [(gogoproto.nullable)=false]; 295 | int64 power = 3; 296 | } 297 | 298 | // ValidatorUpdate 299 | message ValidatorUpdate { 300 | PubKey pub_key = 1 [(gogoproto.nullable)=false]; 301 | int64 power = 2; 302 | } 303 | 304 | // VoteInfo 305 | message VoteInfo { 306 | Validator validator = 1 [(gogoproto.nullable)=false]; 307 | bool signed_last_block = 2; 308 | } 309 | 310 | message PubKey { 311 | string type = 1; 312 | bytes data = 2; 313 | } 314 | 315 | message Evidence { 316 | string type = 1; 317 | Validator validator = 2 [(gogoproto.nullable)=false]; 318 | int64 height = 3; 319 | google.protobuf.Timestamp time = 4 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true]; 320 | int64 total_voting_power = 5; 321 | } 322 | 323 | //---------------------------------------- 324 | // Service Definition 325 | 326 | service ABCIApplication { 327 | rpc Echo(RequestEcho) returns (ResponseEcho) ; 328 | rpc Flush(RequestFlush) returns (ResponseFlush); 329 | rpc Info(RequestInfo) returns (ResponseInfo); 330 | rpc SetOption(RequestSetOption) returns (ResponseSetOption); 331 | rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); 332 | rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); 333 | rpc Query(RequestQuery) returns (ResponseQuery); 334 | rpc Commit(RequestCommit) returns (ResponseCommit); 335 | rpc InitChain(RequestInitChain) returns (ResponseInitChain); 336 | rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); 337 | rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); 338 | } 339 | -------------------------------------------------------------------------------- /protofiles/abci/github.com/tendermint/tendermint/crypto/merkle/merkle.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package merkle; 3 | 4 | // For more information on gogo.proto, see: 5 | // https://github.com/gogo/protobuf/blob/master/extensions.md 6 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 7 | 8 | option (gogoproto.marshaler_all) = true; 9 | option (gogoproto.unmarshaler_all) = true; 10 | option (gogoproto.sizer_all) = true; 11 | 12 | option (gogoproto.populate_all) = true; 13 | option (gogoproto.equal_all) = true; 14 | 15 | //---------------------------------------- 16 | // Message types 17 | 18 | // ProofOp defines an operation used for calculating Merkle root 19 | // The data could be arbitrary format, providing nessecary data 20 | // for example neighbouring node hash 21 | message ProofOp { 22 | string type = 1; 23 | bytes key = 2; 24 | bytes data = 3; 25 | } 26 | 27 | // Proof is Merkle proof defined by the list of ProofOps 28 | message Proof { 29 | repeated ProofOp ops = 1 [(gogoproto.nullable)=false]; 30 | } 31 | -------------------------------------------------------------------------------- /protofiles/abci/github.com/tendermint/tendermint/libs/common/types.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package common; 3 | 4 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 5 | 6 | option (gogoproto.marshaler_all) = true; 7 | option (gogoproto.unmarshaler_all) = true; 8 | option (gogoproto.sizer_all) = true; 9 | option (gogoproto.goproto_registration) = true; 10 | // Generate tests 11 | option (gogoproto.populate_all) = true; 12 | option (gogoproto.equal_all) = true; 13 | option (gogoproto.testgen_all) = true; 14 | 15 | //---------------------------------------- 16 | // Abstract types 17 | 18 | // Define these here for compatibility but use tmlibs/common.KVPair. 19 | message KVPair { 20 | bytes key = 1; 21 | bytes value = 2; 22 | } 23 | 24 | // Define these here for compatibility but use tmlibs/common.KI64Pair. 25 | message KI64Pair { 26 | bytes key = 1; 27 | int64 value = 2; 28 | } 29 | -------------------------------------------------------------------------------- /protofiles/abci/google/protobuf/timestamp.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "github.com/golang/protobuf/ptypes/timestamp"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "TimestampProto"; 40 | option java_multiple_files = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // A Timestamp represents a point in time independent of any time zone or local 44 | // calendar, encoded as a count of seconds and fractions of seconds at 45 | // nanosecond resolution. The count is relative to an epoch at UTC midnight on 46 | // January 1, 1970, in the proleptic Gregorian calendar which extends the 47 | // Gregorian calendar backwards to year one. 48 | // 49 | // All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap 50 | // second table is needed for interpretation, using a [24-hour linear 51 | // smear](https://developers.google.com/time/smear). 52 | // 53 | // The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By 54 | // restricting to that range, we ensure that we can convert to and from [RFC 55 | // 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. 56 | // 57 | // # Examples 58 | // 59 | // Example 1: Compute Timestamp from POSIX `time()`. 60 | // 61 | // Timestamp timestamp; 62 | // timestamp.set_seconds(time(NULL)); 63 | // timestamp.set_nanos(0); 64 | // 65 | // Example 2: Compute Timestamp from POSIX `gettimeofday()`. 66 | // 67 | // struct timeval tv; 68 | // gettimeofday(&tv, NULL); 69 | // 70 | // Timestamp timestamp; 71 | // timestamp.set_seconds(tv.tv_sec); 72 | // timestamp.set_nanos(tv.tv_usec * 1000); 73 | // 74 | // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. 75 | // 76 | // FILETIME ft; 77 | // GetSystemTimeAsFileTime(&ft); 78 | // UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; 79 | // 80 | // // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z 81 | // // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. 82 | // Timestamp timestamp; 83 | // timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); 84 | // timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); 85 | // 86 | // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. 87 | // 88 | // long millis = System.currentTimeMillis(); 89 | // 90 | // Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) 91 | // .setNanos((int) ((millis % 1000) * 1000000)).build(); 92 | // 93 | // 94 | // Example 5: Compute Timestamp from current time in Python. 95 | // 96 | // timestamp = Timestamp() 97 | // timestamp.GetCurrentTime() 98 | // 99 | // # JSON Mapping 100 | // 101 | // In JSON format, the Timestamp type is encoded as a string in the 102 | // [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the 103 | // format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" 104 | // where {year} is always expressed using four digits while {month}, {day}, 105 | // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional 106 | // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), 107 | // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone 108 | // is required. A proto3 JSON serializer should always use UTC (as indicated by 109 | // "Z") when printing the Timestamp type and a proto3 JSON parser should be 110 | // able to accept both UTC and other timezones (as indicated by an offset). 111 | // 112 | // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 113 | // 01:30 UTC on January 15, 2017. 114 | // 115 | // In JavaScript, one can convert a Date object to this format using the 116 | // standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] 117 | // method. In Python, a standard `datetime.datetime` object can be converted 118 | // to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) 119 | // with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one 120 | // can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( 121 | // http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D 122 | // ) to obtain a formatter capable of generating timestamps in this format. 123 | // 124 | // 125 | message Timestamp { 126 | 127 | // Represents seconds of UTC time since Unix epoch 128 | // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 129 | // 9999-12-31T23:59:59Z inclusive. 130 | int64 seconds = 1; 131 | 132 | // Non-negative fractions of a second at nanosecond resolution. Negative 133 | // second values with fractions must still have non-negative nanos values 134 | // that count forward in time. Must be from 0 to 999,999,999 135 | // inclusive. 136 | int32 nanos = 2; 137 | } 138 | -------------------------------------------------------------------------------- /protofiles/lc/access_path.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | message AccessPath { 9 | bytes address = 1; 10 | bytes path = 2; 11 | } 12 | -------------------------------------------------------------------------------- /protofiles/lc/account_state_blob.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | import "proof.proto"; 9 | 10 | message AccountStateBlob { bytes blob = 1; } 11 | 12 | message AccountStateWithProof { 13 | uint64 version = 1; 14 | AccountStateBlob blob = 2; 15 | AccountStateProof proof = 3; 16 | } 17 | -------------------------------------------------------------------------------- /protofiles/lc/admission_control.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package admission_control; 7 | 8 | import "get_with_proof.proto"; 9 | import "mempool_status.proto"; 10 | import "transaction.proto"; 11 | import "vm_errors.proto"; 12 | 13 | // ----------------------------------------------------------------------------- 14 | // ---------------- Submit transaction 15 | // ----------------------------------------------------------------------------- 16 | // The request for transaction submission. 17 | message SubmitTransactionRequest { 18 | // Transaction signed by wallet. 19 | types.SignedTransaction signed_txn = 1; 20 | } 21 | 22 | // AC response status containing code and optionally an error message. 23 | message AdmissionControlStatus { 24 | AdmissionControlStatusCode code = 1; 25 | string message = 2; 26 | } 27 | 28 | // Additional statuses that are possible from admission control in addition 29 | // to VM statuses. 30 | enum AdmissionControlStatusCode { 31 | // Validator accepted the transaction. 32 | Accepted = 0; 33 | // The sender is blacklisted. 34 | Blacklisted = 1; 35 | // The transaction is rejected, e.g. due to incorrect signature. 36 | Rejected = 2; 37 | } 38 | 39 | // The response for transaction submission. 40 | // 41 | // How does a client know if their transaction was included? 42 | // A response from the transaction submission only means that the transaction 43 | // was successfully added to mempool, but not that it is guaranteed to be 44 | // included in the chain. Each transaction should include an expiration time in 45 | // the signed transaction. Let's call this T0. As a client, I submit my 46 | // transaction to a validator. I now need to poll for the transaction I 47 | // submitted. I can use the query that takes my account and sequence number. If 48 | // I receive back that the transaction is completed, I will verify the proofs to 49 | // ensure that this is the transaction I expected. If I receive a response that 50 | // my transaction is not yet completed, I must check the latest timestamp in the 51 | // ledgerInfo that I receive back from the query. If this time is greater than 52 | // T0, I can be certain that my transaction will never be included. If this 53 | // time is less than T0, I need to continue polling. 54 | message SubmitTransactionResponse { 55 | // The status of a transaction submission can either be a VM status, or 56 | // some other admission control/mempool specific status e.g. Blacklisted. 57 | oneof status { 58 | types.VMStatus vm_status = 1; 59 | AdmissionControlStatus ac_status = 2; 60 | mempool.MempoolAddTransactionStatus mempool_status = 3; 61 | } 62 | // Public key(id) of the validator that processed this transaction 63 | bytes validator_id = 4; 64 | } 65 | 66 | // ----------------------------------------------------------------------------- 67 | // ---------------- Service definition 68 | // ----------------------------------------------------------------------------- 69 | service AdmissionControl { 70 | // Public API to submit transaction to a validator. 71 | rpc SubmitTransaction(SubmitTransactionRequest) 72 | returns (SubmitTransactionResponse) {} 73 | 74 | // This API is used to update the client to the latest ledger version and 75 | // optionally also request 1..n other pieces of data. This allows for batch 76 | // queries. All queries return proofs that a client should check to validate 77 | // the data. Note that if a client only wishes to update to the latest 78 | // LedgerInfo and receive the proof of this latest version, they can simply 79 | // omit the requested_items (or pass an empty list) 80 | rpc UpdateToLatestLedger( 81 | types.UpdateToLatestLedgerRequest) 82 | returns (types.UpdateToLatestLedgerResponse) {} 83 | } 84 | -------------------------------------------------------------------------------- /protofiles/lc/consensus.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package network; 7 | 8 | import "ledger_info.proto"; 9 | import "transaction.proto"; 10 | 11 | message ConsensusMsg { 12 | oneof message { 13 | Proposal proposal = 1; 14 | Vote vote = 2; 15 | RequestBlock request_block = 3; 16 | RespondBlock respond_block = 4; 17 | TimeoutMsg timeout_msg = 5; 18 | SyncInfo sync_info = 6; 19 | } 20 | } 21 | 22 | message Proposal { 23 | // The proposed block 24 | Block proposed_block = 1; 25 | // Information about the highest QC, LedgerInfo, TimeoutCertificate, etc. 26 | SyncInfo sync_info = 2; 27 | } 28 | 29 | message PacemakerTimeout { 30 | // Round that has timed out (e.g. we propose to switch to round + 1) 31 | uint64 round = 1; 32 | // Author of timeout 33 | bytes author = 2; 34 | // Signature that this timeout was authored by owner 35 | bytes signature = 3; 36 | // Optional vote for the given round 37 | Vote vote = 4; 38 | } 39 | 40 | message TimeoutMsg { 41 | // Information about the highest QC, LedgerInfo, TimeoutCertificate, etc. 42 | SyncInfo sync_info = 1; 43 | // Timeout 44 | PacemakerTimeout pacemaker_timeout = 2; 45 | // Signature that this timeout was authored by owner 46 | bytes signature = 3; 47 | } 48 | 49 | message SyncInfo { 50 | // Highest quorum certificate 51 | QuorumCert highest_quorum_cert = 1; 52 | // Highest ledger info 53 | QuorumCert highest_ledger_info = 2; 54 | // Optional highest timeout certificate if available 55 | PacemakerTimeoutCertificate highest_timeout_cert = 3; 56 | } 57 | 58 | message PacemakerTimeoutCertificate { 59 | // Round for which this certificate was created 60 | uint64 round = 1; 61 | // List of certified timeouts 62 | repeated PacemakerTimeout timeouts = 2; 63 | } 64 | 65 | message Block { 66 | // This block's id as a hash value 67 | bytes id = 1; 68 | // Parent block id of this block as a hash value (all zeros to indicate the 69 | // genesis block) 70 | bytes parent_id = 2; 71 | // Payload of the block (e.g. one or more transaction(s) 72 | bytes payload = 3; 73 | // The round of the block (internal monotonically increasing counter). 74 | uint64 round = 4; 75 | // The height of the block (position in the chain). 76 | uint64 height = 5; 77 | // The approximate physical microseconds since the epoch when the block was proposed 78 | uint64 timestamp_usecs = 6; 79 | // Contains the quorum certified ancestor and whether the quorum certified 80 | // ancestor was voted on successfully 81 | QuorumCert quorum_cert = 7; 82 | // Author of the block that can be validated by the author's public key and 83 | // the signature 84 | bytes author = 8; 85 | // Signature that the hash of this block has been authored by the owner of the 86 | // private key 87 | bytes signature = 9; 88 | } 89 | 90 | message QuorumCert { 91 | // Ancestor of this block (could be a parent) 92 | bytes block_id = 1; 93 | /// The execution state id of the corresponding block 94 | bytes state_id = 2; 95 | uint64 version = 3; 96 | /// The round of a certified block. 97 | uint64 round = 4; 98 | // LedgerInfo with at least 2f+1 signatures. The LedgerInfo's consensus data 99 | // hash is a digest that covers ancestor_id, state_id and round. 100 | types.LedgerInfoWithSignatures signed_ledger_info = 5; 101 | // The id of the parent block of the certified block 102 | bytes parent_block_id = 6; 103 | // The round of the parent block of the certified block 104 | uint64 parent_block_round = 7; 105 | // The id of the grandparent block of the certified block 106 | bytes grandparent_block_id = 8; 107 | // The round of the grandparent block of the certified block 108 | uint64 grandparent_block_round = 9; 109 | } 110 | 111 | message Vote { 112 | // The id of the proposed block. 113 | bytes proposed_block_id = 1; 114 | // The id of the state generated by the StateExecutor after executing the 115 | // proposed block. 116 | bytes executed_state_id = 2; 117 | uint64 version = 3; 118 | uint64 round = 4; 119 | // Author of the vote. 120 | bytes author = 5; 121 | // The ledger info carried with the vote (corresponding to the block of a 122 | // potentially committed txn). 123 | types.LedgerInfo ledger_info = 6; 124 | // Signature of the ledger info. 125 | bytes signature = 7; 126 | // The id of the parent block of the proposed block 127 | bytes parent_block_id = 8; 128 | // The round of the parent block of the proposed block 129 | uint64 parent_block_round = 9; 130 | // The id of the grandparent block of the proposed block 131 | bytes grandparent_block_id = 10; 132 | // The round of the grandparent block of the proposed block 133 | uint64 grandparent_block_round = 11; 134 | } 135 | 136 | message RequestBlock { 137 | // The id of the requested block. 138 | bytes block_id = 1; 139 | uint64 num_blocks = 2; 140 | } 141 | 142 | enum BlockRetrievalStatus { 143 | // Successfully fill in the request. 144 | SUCCEEDED = 0; 145 | // Can not find the block corresponding to block_id. 146 | ID_NOT_FOUND = 1; 147 | // Can not find enough blocks but find some. 148 | NOT_ENOUGH_BLOCKS = 2; 149 | } 150 | 151 | message RespondBlock { 152 | BlockRetrievalStatus status = 1; 153 | // The responded block. 154 | repeated Block blocks = 2; 155 | } 156 | -------------------------------------------------------------------------------- /protofiles/lc/crates/admission-control.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/admission-control.md -------------------------------------------------------------------------------- /protofiles/lc/crates/bytecode-verifier.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/bytecode-verifier.md -------------------------------------------------------------------------------- /protofiles/lc/crates/consensus.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/consensus.md -------------------------------------------------------------------------------- /protofiles/lc/crates/crypto.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/crypto.md -------------------------------------------------------------------------------- /protofiles/lc/crates/execution.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/execution.md -------------------------------------------------------------------------------- /protofiles/lc/crates/ir-to-bytecode.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/ir-to-bytecode.md -------------------------------------------------------------------------------- /protofiles/lc/crates/mempool.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/mempool.md -------------------------------------------------------------------------------- /protofiles/lc/crates/move-language.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/move-language.md -------------------------------------------------------------------------------- /protofiles/lc/crates/network.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/network.md -------------------------------------------------------------------------------- /protofiles/lc/crates/storage.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/storage.md -------------------------------------------------------------------------------- /protofiles/lc/crates/vm.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xsutD7YBMiZCkgV9uxxJ6Z/movemint/90978483fd2401e9091aae74f9547d02caa8d344/protofiles/lc/crates/vm.md -------------------------------------------------------------------------------- /protofiles/lc/events.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // This file contains proto definitions related to events. Events are emitted 5 | // by smart contract execution. These could include events such as received 6 | // transactions, sent transactions, etc. 7 | 8 | syntax = "proto3"; 9 | 10 | package types; 11 | 12 | import "access_path.proto"; 13 | import "proof.proto"; 14 | 15 | // An event emitted from a smart contract 16 | message Event { 17 | AccessPath access_path = 1; 18 | uint64 sequence_number = 2; 19 | bytes event_data = 3; 20 | } 21 | 22 | // An event along with the proof for the event 23 | message EventWithProof { 24 | uint64 transaction_version = 1; 25 | uint64 event_index = 2; 26 | Event event = 3; 27 | EventProof proof = 4; 28 | } 29 | 30 | // A list of events. 31 | message EventsList { 32 | repeated Event events = 1; 33 | } 34 | 35 | // A list of EventList's, each representing all events for a transaction. 36 | message EventsForVersions { 37 | repeated EventsList events_for_version = 1; 38 | } 39 | -------------------------------------------------------------------------------- /protofiles/lc/execution.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package execution; 7 | 8 | import "get_with_proof.proto"; 9 | import "ledger_info.proto"; 10 | import "transaction.proto"; 11 | import "validator_set.proto"; 12 | import "vm_errors.proto"; 13 | 14 | // ----------------------------------------------------------------------------- 15 | // ---------------- Execution Service Definition 16 | // ----------------------------------------------------------------------------- 17 | service Execution { 18 | // Execute a list of signed transactions given by consensus. Return the id 19 | // of the block and the root hash of the ledger after applying transactions 20 | // in this block. 21 | rpc ExecuteBlock(ExecuteBlockRequest) returns (ExecuteBlockResponse) {} 22 | 23 | // Commit a previously executed block that has been agreed by consensus. 24 | rpc CommitBlock(CommitBlockRequest) returns (CommitBlockResponse) {} 25 | 26 | // Execute and commit a list of signed transactions received from peer 27 | // during synchronization. Return the id of the block 28 | rpc ExecuteChunk(ExecuteChunkRequest) returns (ExecuteChunkResponse) {} 29 | } 30 | 31 | message ExecuteBlockRequest { 32 | // The list of transactions from consensus. 33 | repeated types.SignedTransaction transactions = 1; 34 | 35 | // Id of the parent block. 36 | // We're going to use a special GENESIS_BLOCK_ID constant defined in 37 | // crypto::hash module to refer to the block id of the Genesis block, which is 38 | // executed in a special way. 39 | bytes parent_block_id = 2; 40 | 41 | // Id of the current block. 42 | bytes block_id = 3; 43 | } 44 | 45 | // Result of transaction execution. 46 | message ExecuteBlockResponse { 47 | // Root hash of the ledger after applying all the transactions in this 48 | // block. 49 | bytes root_hash = 1; 50 | 51 | // The execution result of the transactions. Each transaction has a status 52 | // field that indicates whether it should be included in the ledger once the 53 | // block is committed. 54 | repeated types.VMStatus status = 2; 55 | 56 | // The corresponding ledger version when this block is committed. 57 | uint64 version = 3; 58 | 59 | // If set, this field designates that if this block is committed, then the 60 | // next epoch will start immediately with the included set of validators. 61 | types.ValidatorSet validators = 4; 62 | } 63 | 64 | message CommitBlockRequest { 65 | // The ledger info with signatures from 2f+1 validators. It contains the id 66 | // of the block consensus wants to commit. This will cause the given block 67 | // and all the uncommitted ancestors to be committed to storage. 68 | types.LedgerInfoWithSignatures ledger_info_with_sigs = 1; 69 | } 70 | 71 | message CommitBlockResponse { CommitBlockStatus status = 1; } 72 | 73 | enum CommitBlockStatus { 74 | // The block is persisted. 75 | SUCCEEDED = 0; 76 | 77 | // Something went wrong. 78 | FAILED = 1; 79 | } 80 | 81 | // Ask Execution service to execute and commit a chunk of contiguous 82 | // transactions. All the transactions in this chunk should belong to the same 83 | // epoch E. If the caller has a list of transactions that span two epochs, it 84 | // should split the transactions. 85 | message ExecuteChunkRequest { 86 | types.TransactionListWithProof txn_list_with_proof = 1; 87 | types.LedgerInfoWithSignatures ledger_info_with_sigs = 2; 88 | } 89 | 90 | // Either all transactions are successfully executed and persisted, or nothing 91 | // happens. 92 | message ExecuteChunkResponse {} 93 | -------------------------------------------------------------------------------- /protofiles/lc/get_with_proof.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // This file contains proto definitions for performing queries and getting back 5 | // results with proofs. This is the interface for a client to query data from 6 | // the system. Every query result must include proof so that a client can be 7 | // certain that the data returned is valid. A client must verify this proof to 8 | // ensure that a node isn't lying to them. 9 | 10 | // How to verify the response as a client: 11 | // (Note that every response comes in the form of GetWithProofResponse which 12 | // wraps the inner response elements that correspond to the specific request 13 | // types. Below we will assume a single request/response type. The 14 | // verification can be extended as needed for multiple types. Also note that we 15 | // will use the following notation: resp = GetWithProofResponse and req = 16 | // GetWithProofRequest). Also note that the following will be considered 17 | // equivalent for brevity: req.requested_items.get_account_state_request == 18 | // req.get_account_state_request And, resp.values.get_account_state_response == 19 | // resp.get_account_state_response 20 | // 21 | // GetAccountStateResponse: 22 | // - let state_req = req.requested_items.get_account_state_request; 23 | // - let state_resp = resp.values.get_account_state_response; 24 | // - Verify that: 25 | // - state_req.access_path == state_resp.access_path 26 | // - This ensures that the server is responding with the correct access 27 | // path 28 | // - let state_data_hash = Hash(state_resp.value); 29 | // - let state_proof = resp.values.proof.state_proof_value.sparse_merkle_proof; 30 | // - Validate state_proof using state_data_hash as the leaf 31 | // - When verifying the state tree, use: 32 | // state_root_hash = resp.values.transaction_info.state_root_hash 33 | // - Validate accumulator using resp.values.transaction_info as the leaf 34 | // - When verifying the accumulator, use: 35 | // root_hash = 36 | // resp.ledger_info_with_sigs.ledger_info.ledger_info.txn_root_hash; 37 | // - Validate that the transaction root hash submitted in 38 | // req.known_value.node_value.txn_root_hash 39 | // exists in the proof for accumulator and that the proof is valid with 40 | // this hash 41 | // - Validate ledger info 42 | // - let ledger_info_hash = 43 | // Hash(resp.ledger_info_with_sigs.ledger_info.ledger_info); 44 | // - Verify signatures from resp.ledger_info_with_sigs.signatures are 45 | // signing 46 | // ledger_info_hash and that there are >2/3 nodes signing this 47 | // correctly 48 | // - Validate that the timestamp is relatively recent in 49 | // resp.ledger_info_with_sigs.ledger_info.timestamp 50 | // 51 | // 52 | // GetAccountTransactionBySequenceNumberResponse: 53 | // - Note that other than type completed_transaction, there will be no proof 54 | // returned 55 | // since the transaction has not yet been committed. To ensure that a 56 | // validator is telling the truth about it not being committed yet, a 57 | // client should query for their account state and verify that their 58 | // current sequence number is less than what they are searching for with 59 | // GetAccountTransactionBySequenceNumberResponse 60 | // - let txn = 61 | // resp.get_account_transaction_by_sequence_number_response.transaction.committed_transaction; 62 | // - let txn_hash = Hash(txn); 63 | // - Verify that resp.proof.transaction_info.signed_transaction_hash == txn_hash 64 | // - Validate accumulator using resp.proof.transaction_info as the leaf 65 | // - When verifying the accumulator, use: 66 | // root_hash = 67 | // resp.ledger_info_with_sigs.ledger_info.ledger_info.txn_root_hash; 68 | // - Validate that the transaction root hash submitted in 69 | // req.known_value.node_value.txn_root_hash 70 | // exists in the proof for accumulator and that the proof is valid with 71 | // this hash 72 | // - Validate ledger info 73 | // - let ledger_info_hash = 74 | // Hash(resp.ledger_info_with_sigs.ledger_info.ledger_info); 75 | // - Verify signatures from resp.ledger_info_with_sigs.signatures are 76 | // signing 77 | // ledger_info_hash and that there are >2/3 nodes signing this 78 | // correctly 79 | // - Validate that the timestamp is relatively recent in 80 | // resp.ledger_info_with_sigs.ledger_info.timestamp 81 | // 82 | // 83 | // GetTransactionsResponse: 84 | // - for txn in resp.get_transactions_response.transactions: 85 | // - let txn = txn.committed_transaction; 86 | // - let txn_hash = Hash(txn); 87 | // - Verify that txn.proof.transaction_info.signed_transaction_hash == 88 | // txn_hash 89 | // - Validate accumulator using txn.proof.transaction_info as the leaf 90 | // - When verifying the accumulator, use: 91 | // root_hash = 92 | // resp.ledger_info_with_sigs.ledger_info.ledger_info.txn_root_hash; 93 | // - Verify that transactions are sequential and none are missing 94 | // - Validate ledger info 95 | // - let ledger_info_hash = 96 | // Hash(resp.ledger_info_with_sigs.ledger_info.ledger_info); 97 | // - Verify signatures from resp.ledger_info_with_sigs.signatures are 98 | // signing 99 | // ledger_info_hash and that there are >2/3 nodes signing this 100 | // correctly 101 | // - Validate that the timestamp is relatively recent in 102 | // resp.ledger_info_with_sigs.ledger_info.timestamp 103 | // - If the number of transactions returned is less than limit for an ascending 104 | // query 105 | // or if the requested offset > current version for a descending query, 106 | // the client should verify that the timestamp in ledger info is relatively 107 | // recent to determine if it is likely that all transactions available were 108 | // returned 109 | syntax = "proto3"; 110 | 111 | package types; 112 | 113 | import "access_path.proto"; 114 | import "account_state_blob.proto"; 115 | import "events.proto"; 116 | import "ledger_info.proto"; 117 | import "transaction.proto"; 118 | import "validator_change.proto"; 119 | 120 | // ----------------------------------------------------------------------------- 121 | // ---------------- Update to latest ledger request 122 | // ----------------------------------------------------------------------------- 123 | 124 | // This API is used to update the client to the latest ledger version and 125 | // optionally also request 1..n other pieces of data. This allows for batch 126 | // queries. All queries return proofs that a client should check to validate 127 | // the data. 128 | // 129 | // Note that if a client only wishes to update to the latest LedgerInfo and 130 | // receive the proof that this latest ledger extends the client_known_version 131 | // ledger the client had, they can simply set the requested_items to an empty 132 | // list. 133 | message UpdateToLatestLedgerRequest { 134 | // This is the version the client already trusts. Usually the client should 135 | // set this to the version it obtained the last time it synced with the 136 | // chain. If this is the first time ever the client sends a request, it must 137 | // use the waypoint hard-coded in its software. 138 | uint64 client_known_version = 1; 139 | 140 | // The items for which we are requesting data in this API call. 141 | repeated RequestItem requested_items = 2; 142 | } 143 | 144 | message RequestItem { 145 | oneof requested_items { 146 | GetAccountStateRequest get_account_state_request = 1; 147 | GetAccountTransactionBySequenceNumberRequest 148 | get_account_transaction_by_sequence_number_request = 2; 149 | GetEventsByEventAccessPathRequest get_events_by_event_access_path_request = 150 | 3; 151 | GetTransactionsRequest get_transactions_request = 4; 152 | } 153 | } 154 | 155 | // ----------------------------------------------------------------------------- 156 | // ---------------- Update to latest ledger response 157 | // ----------------------------------------------------------------------------- 158 | 159 | // Response from getting latest ledger 160 | message UpdateToLatestLedgerResponse { 161 | // Responses to the queries posed by the requests. The proofs generated will 162 | // be relative to the version of the latest ledger provided below. 163 | repeated ResponseItem response_items = 1; 164 | 165 | // The latest ledger info this node has. It will come with at least 2f+1 166 | // validator signatures as well as a proof that shows the latest ledger 167 | // extends the old ledger the client had. 168 | LedgerInfoWithSignatures ledger_info_with_sigs = 2; 169 | 170 | // Validator change events from what the client last knew. This is used to 171 | // inform the client of validator changes from the client's last known version 172 | // until the current version 173 | repeated ValidatorChangeEventWithProof validator_change_events = 3; 174 | } 175 | 176 | // Individual response items to the queries posed by the requests 177 | message ResponseItem { 178 | oneof response_items { 179 | GetAccountStateResponse get_account_state_response = 3; 180 | GetAccountTransactionBySequenceNumberResponse 181 | get_account_transaction_by_sequence_number_response = 4; 182 | GetEventsByEventAccessPathResponse get_events_by_event_access_path_response = 5; 183 | GetTransactionsResponse get_transactions_response = 6; 184 | } 185 | } 186 | 187 | // ----------------------------------------------------------------------------- 188 | // ---------------- Get account state (balance, sequence number, etc.) 189 | // ----------------------------------------------------------------------------- 190 | 191 | // Gets latest state for an account. 192 | message GetAccountStateRequest { 193 | // Account for which we are fetching the state. 194 | bytes address = 1; 195 | } 196 | 197 | // State information returned by a get account state query. 198 | message GetAccountStateResponse { 199 | // Blob value representing the account state together with proof the client 200 | // can utilize to verify it. 201 | AccountStateWithProof account_state_with_proof = 1; 202 | } 203 | 204 | // ----------------------------------------------------------------------------- 205 | // ---------------- Get single transaction by account + sequence number 206 | // ----------------------------------------------------------------------------- 207 | // Get transactions that altered an account - this includes both sent and 208 | // received. A user of this should check that the data returned matches what 209 | // they expect. As an example, a potential attack vector would be something 210 | // like the following: Alice is buying an apple from Bob. Alice's phone signs a 211 | // transaction X with sequence number N that pays coins to Bob. Alice transmits 212 | // this signature to Bob's payment terminal which then submits the transaction 213 | // and checks its status to see if Alice can be given the apple. However, as Bob 214 | // is doing this Alice constructs a second transaction X' also with sequence 215 | // number N. Alice gets that transaction inserted in the blockchain. If Bob 216 | // isn't thoughtful about how he uses this API he may assume that if he asks for 217 | // the N'th transaction on Alice's account that when the API returns that this 218 | // means the transaction has gone through. The point here is that one should be 219 | // careful in reading too much into "transaction X is on the chain" and focus on 220 | // the logs, which tell you what the transaction did. 221 | // 222 | // If a client submitted a transaction, they should also verify that the hash of 223 | // the returned transaction matches what they submitted. As an example, if a 224 | // client has two wallets that share the same account, they may both submit a 225 | // transaction at the same sequence number and only one will be committed. A 226 | // client should never assume that if they receive the response that this 227 | // transaction was included that it means that this is definitely the 228 | // transaction that was submitted. They should check that the hash matches what 229 | // they sent 230 | message GetAccountTransactionBySequenceNumberRequest { 231 | // Account for which to query transactions 232 | bytes account = 1; 233 | 234 | uint64 sequence_number = 2; 235 | 236 | // Set to true to fetch events for the transaction at this version 237 | bool fetch_events = 3; 238 | } 239 | 240 | // Transaction information for transactions requested by 241 | // GetAccountTransactionsRequest 242 | message GetAccountTransactionBySequenceNumberResponse { 243 | // When the transaction requested is committed, return the committed 244 | // transaction with proof. 245 | SignedTransactionWithProof signed_transaction_with_proof = 2; 246 | // When the transaction requested is not committed, we give a proof that 247 | // shows the current sequence number is smaller than what would have been if 248 | // the transaction was committed. 249 | AccountStateWithProof proof_of_current_sequence_number = 3; 250 | } 251 | 252 | // ----------------------------------------------------------------------------- 253 | // ---------------- Get events by event access path 254 | // ----------------------------------------------------------------------------- 255 | 256 | // Get events that exist on an event access path. In the current world, 257 | // a user may specify events that were received, events that were sent, or any 258 | // event that modifies their account 259 | message GetEventsByEventAccessPathRequest { 260 | AccessPath access_path = 1; 261 | 262 | // The sequence number of the event to start with for this query. Use a 263 | // sequence number of MAX_INT to represent the latest. 264 | uint64 start_event_seq_num = 2; 265 | 266 | // If ascending is true this query will return up to `limit` events that were 267 | // emitted after `start_event_seq_num`. Otherwise it will return up to `limit` 268 | // events before the offset. Both cases are inclusive. 269 | bool ascending = 3; 270 | 271 | // Limit number of results 272 | uint64 limit = 4; 273 | } 274 | 275 | message GetEventsByEventAccessPathResponse { 276 | // Returns an event and proof of each of the events in the request. The first 277 | // element of proofs will be the closest to `start_event_seq_num`. 278 | repeated EventWithProof events_with_proof = 1; 279 | 280 | // If the number of events returned is less than `limit` for an ascending 281 | // query or if start_event_seq_num > the latest seq_num for a descending 282 | // query, returns the state of the account containing the given access path 283 | // in the latest state. This allows the client to verify that there are in 284 | // fact no extra events. 285 | // 286 | // The LedgerInfoWithSignatures which is on the main 287 | // UpdateToLatestLedgerResponse can be used to validate this. 288 | AccountStateWithProof proof_of_latest_event = 2; 289 | } 290 | 291 | // ----------------------------------------------------------------------------- 292 | // ---------------- Get transactions 293 | // ----------------------------------------------------------------------------- 294 | 295 | // Get up to limit transactions starting from start_version. 296 | message GetTransactionsRequest { 297 | // The version of the transaction to start with for this query. Use a version 298 | // of MAX_INT to represent the latest. 299 | uint64 start_version = 1; 300 | 301 | // Limit number of results 302 | uint64 limit = 2; 303 | 304 | // Set to true to fetch events for the transaction at each version 305 | bool fetch_events = 3; 306 | } 307 | 308 | message GetTransactionsResponse { 309 | TransactionListWithProof txn_list_with_proof = 1; 310 | } 311 | -------------------------------------------------------------------------------- /protofiles/lc/language_storage.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | /// The unique identifier for a module on the chain. 9 | message ModuleId { 10 | bytes address = 1; 11 | string name = 2; 12 | } 13 | -------------------------------------------------------------------------------- /protofiles/lc/ledger_info.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | /// Even though we don't always need all hashes, we pass them in and return them 9 | /// always so that we keep them in sync on the client and don't make the client 10 | /// worry about which one(s) to pass in which cases 11 | /// 12 | /// This structure serves a dual purpose. 13 | /// 14 | /// First, if this structure is signed by 2f+1 validators it signifies the state 15 | /// of the ledger at version `version` -- it contains the transaction 16 | /// accumulator at that version which commits to all historical transactions. 17 | /// This structure may be expanded to include other information that is derived 18 | /// from that accumulator (e.g. the current time according to the time contract) 19 | /// to reduce the number of proofs a client must get. 20 | /// 21 | /// Second, the structure contains a `consensus_data_hash` value. This is the 22 | /// hash of an internal data structure that represents a block that is voted on 23 | /// by consensus. 24 | /// 25 | /// Combining these two concepts when the consensus algorithm votes on a block B 26 | /// it votes for a LedgerInfo with the `version` being the latest version that 27 | /// will be committed if B gets 2f+1 votes. It sets `consensus_data_hash` to 28 | /// represent B so that if those 2f+1 votes are gathered, the block is valid to 29 | /// commit 30 | message LedgerInfo { 31 | // Current latest version of the system 32 | uint64 version = 1; 33 | 34 | // Root hash of transaction accumulator at this version 35 | bytes transaction_accumulator_hash = 2; 36 | 37 | // Hash of consensus-specific data that is opaque to all parts of the system 38 | // other than consensus. This is needed to verify signatures because 39 | // consensus signing includes this hash 40 | bytes consensus_data_hash = 3; 41 | 42 | // The block id of the last committed block corresponding to this ledger info. 43 | // This field is not particularly interesting to the clients, but can be used 44 | // by the validators for synchronization. 45 | bytes consensus_block_id = 4; 46 | 47 | // Epoch number corresponds to the set of validators that are active for this 48 | // ledger info. The main motivation for keeping the epoch number in the 49 | // LedgerInfo is to ensure that the client has enough information to verify 50 | // that the signatures for this info are coming from the validators that 51 | // indeed form a quorum. Without epoch number a potential attack could reuse 52 | // the signatures from the validators in one epoch in order to sign the wrong 53 | // info belonging to another epoch, in which these validators do not form a 54 | // quorum. The very first epoch number is 0. 55 | uint64 epoch_num = 5; 56 | 57 | // Timestamp that represents the microseconds since the epoch (unix time) that is 58 | // generated by the proposer of the block. This is strictly increasing with every block. 59 | // If a client reads a timestamp > the one they specified for transaction expiration time, 60 | // they can be certain that their transaction will never be included in a block in the future 61 | // (assuming that their transaction has not yet been included) 62 | uint64 timestamp_usecs = 6; 63 | } 64 | 65 | /// The validator node returns this structure which includes signatures 66 | /// from each validator to confirm the state. The client needs to only pass 67 | /// back the LedgerInfo element since the validator node doesn't need to know 68 | /// the signatures again when the client performs a query, those are only there 69 | /// for the client to be able to verify the state 70 | message LedgerInfoWithSignatures { 71 | // Signatures of the root node from each validator 72 | repeated ValidatorSignature signatures = 1; 73 | 74 | LedgerInfo ledger_info = 2; 75 | } 76 | 77 | message ValidatorSignature { 78 | // The account address of the validator, which can be used for retrieving its 79 | // public key during the given epoch. 80 | bytes validator_id = 1; 81 | bytes signature = 2; 82 | } 83 | -------------------------------------------------------------------------------- /protofiles/lc/mempool.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package network; 7 | 8 | import "transaction.proto"; 9 | 10 | /* MempoolSyncMsg represents the messages exchanging between validators to keep 11 | * transactions in sync. The proto definition provides the spec on the wire so 12 | * that others can implement their mempool service in various languages. 13 | * Mempool service is responsible for sending and receiving MempoolSyncMsg 14 | * across validators. */ 15 | message MempoolSyncMsg { 16 | bytes peer_id = 1; 17 | repeated types.SignedTransaction transactions = 2; 18 | } 19 | -------------------------------------------------------------------------------- /protofiles/lc/mempool_status.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package mempool; 7 | 8 | enum MempoolAddTransactionStatusCode { 9 | // Transaction was sent to Mempool 10 | Valid = 0; 11 | // The sender does not have enough balance for the transaction. 12 | InsufficientBalance = 1; 13 | // Sequence number is old, etc. 14 | InvalidSeqNumber = 2; 15 | // Mempool is full (reached max global capacity) 16 | MempoolIsFull = 3; 17 | // Account reached max capacity per account 18 | TooManyTransactions = 4; 19 | // Invalid update. Only gas price increase is allowed 20 | InvalidUpdate = 5; 21 | } 22 | 23 | message MempoolAddTransactionStatus { 24 | MempoolAddTransactionStatusCode code = 1; 25 | string message = 2; 26 | } 27 | -------------------------------------------------------------------------------- /protofiles/lc/network.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package network; 7 | 8 | // A `PeerInfo` represents the network address(es) of a Peer at some epoch. 9 | message PeerInfo { 10 | // Addresses this peer can be reached at. 11 | // An address is a byte array in the 12 | // [multiaddr](https://multiformats.io/multiaddr/) format. 13 | repeated bytes addrs = 1; 14 | // Monotonically increasing incarnation number. This is usually a timestamp. 15 | uint64 epoch = 2; 16 | } 17 | 18 | // A `Note` represents a signed PeerInfo. The signature should be of the peer 19 | // whose info is being sent. 20 | message Note { 21 | // Id of the peer. 22 | bytes peer_id = 1; 23 | // Serialized PeerInfo. 24 | bytes peer_info = 2; 25 | // Each peer signs its serialized PeerInfo and includes both the PeerInfo and 26 | // the sign in a note it sends to another peer. 27 | bytes signature = 3; 28 | } 29 | 30 | // Discovery message exchanged as part of the discovery protocol. 31 | // The discovery message sent by a peer consists of notes for all the peers the 32 | // sending peer knows about. 33 | message DiscoveryMsg { repeated Note notes = 1; } 34 | 35 | // Identity message exchanged as part of the Identity protocol. 36 | message IdentityMsg { 37 | bytes peer_id = 1; 38 | repeated bytes supported_protocols = 2; 39 | } 40 | 41 | // Ping message sent as liveness probe. 42 | message Ping {} 43 | 44 | // Pong message sent as response to liveness probe. 45 | message Pong {} 46 | -------------------------------------------------------------------------------- /protofiles/lc/node_debug_interface.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // A Debugging interface to be used to query debug information from a Node 5 | syntax = "proto3"; 6 | 7 | package debug; 8 | 9 | message GetNodeDetailsRequest {} 10 | 11 | message GetNodeDetailsResponse { map stats = 1; } 12 | 13 | message DumpJemallocHeapProfileRequest {} 14 | 15 | message DumpJemallocHeapProfileResponse { 16 | // Status code from jemalloc mallctl call. 0 indicates success. 17 | int32 status_code = 1; 18 | } 19 | 20 | service NodeDebugInterface { 21 | // Returns debug information about node 22 | rpc GetNodeDetails(GetNodeDetailsRequest) returns (GetNodeDetailsResponse) {} 23 | 24 | // Triggers a dump of heap profile. 25 | rpc DumpJemallocHeapProfile(DumpJemallocHeapProfileRequest) 26 | returns (DumpJemallocHeapProfileResponse) {} 27 | } 28 | -------------------------------------------------------------------------------- /protofiles/lc/proof.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | import "transaction_info.proto"; 9 | 10 | message AccumulatorProof { 11 | // The bitmap indicating which siblings are default. 1 means non-default and 12 | // 0 means default. The LSB corresponds to the sibling at the bottom of the 13 | // accumulator. The leftmost 1-bit corresponds to the sibling at the level 14 | // just below root level in the accumulator, since this one is always 15 | // non-default. 16 | uint64 bitmap = 1; 17 | 18 | // The non-default siblings. The ones near the root are at the beginning of 19 | // the list. 20 | repeated bytes non_default_siblings = 2; 21 | } 22 | 23 | message SparseMerkleProof { 24 | // This proof can be used to authenticate whether a given leaf exists in the 25 | // tree or not. In Rust: 26 | // - If this is `Some(HashValue, HashValue)` 27 | // - If the first `HashValue` equals requested key, this is an inclusion 28 | // proof and the second `HashValue` equals the hash of the 29 | // corresponding account blob. 30 | // - Otherwise this is a non-inclusion proof. The first `HashValue` is 31 | // the only key that exists in the subtree and the second `HashValue` 32 | // equals the hash of the corresponding account blob. 33 | // - If this is `None`, this is also a non-inclusion proof which indicates 34 | // the subtree is empty. 35 | // 36 | // In protobuf, this leaf field should either be 37 | // - empty, which corresponds to None in the Rust structure. 38 | // - exactly 64 bytes, which corresponds to Some<(HashValue, HashValue)> 39 | // in the Rust structure. 40 | bytes leaf = 1; 41 | 42 | // The bitmap indicating which siblings are default. 1 means non-default and 43 | // 0 means default. The MSB of the first byte corresponds to the sibling at 44 | // the top of the Sparse Merkle Tree. The rightmost 1-bit of the last byte 45 | // corresponds to the sibling at the bottom, since this one is always 46 | // non-default. 47 | bytes bitmap = 2; 48 | 49 | // The non-default siblings. The ones near the root are at the beginning of 50 | // the list. 51 | repeated bytes non_default_siblings = 3; 52 | } 53 | 54 | message AccumulatorConsistencyProof { 55 | // The root hashes of the frozen subtrees that form the small accumulator. 56 | // Note that none of these hashes should be default hash. 57 | repeated bytes frozen_subtree_roots = 1; 58 | 59 | // The total number of siblings. 60 | uint32 num_siblings = 2; 61 | 62 | // The non-default siblings. Note that the entire list of siblings always 63 | // start of zero or more non-default siblings, followed by zero of more 64 | // default siblings. So given the total number of siblings and the non-default 65 | // siblings we should be able to construct the entire sibling list. 66 | repeated bytes non_default_siblings = 3; 67 | } 68 | 69 | // The complete proof used to authenticate a signed transaction. 70 | message SignedTransactionProof { 71 | AccumulatorProof ledger_info_to_transaction_info_proof = 1; 72 | TransactionInfo transaction_info = 2; 73 | } 74 | 75 | // The complete proof used to authenticate an account state. 76 | message AccountStateProof { 77 | AccumulatorProof ledger_info_to_transaction_info_proof = 1; 78 | TransactionInfo transaction_info = 2; 79 | SparseMerkleProof transaction_info_to_account_proof = 3; 80 | } 81 | 82 | // The complete proof used to authenticate an event. 83 | message EventProof { 84 | AccumulatorProof ledger_info_to_transaction_info_proof = 1; 85 | TransactionInfo transaction_info = 2; 86 | AccumulatorProof transaction_info_to_event_proof = 3; 87 | } 88 | -------------------------------------------------------------------------------- /protofiles/lc/secret_service.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package secret_service; 7 | 8 | // ----------------------------------------------------------------------------- 9 | // ---------------- Service definition 10 | // ----------------------------------------------------------------------------- 11 | service SecretService { 12 | // API to request key generation 13 | rpc GenerateKey (GenerateKeyRequest) returns (GenerateKeyResponse) {} 14 | // API to request a public key 15 | rpc GetPublicKey (PublicKeyRequest) returns (PublicKeyResponse) {} 16 | // API to request a signature 17 | rpc Sign (SignRequest) returns (SignResponse) {} 18 | } 19 | 20 | message GenerateKeyRequest { 21 | // Spec gives a way to generate the key (potentially BIP32 private derivation path here) 22 | KeyType spec = 1; 23 | } 24 | 25 | message GenerateKeyResponse { 26 | bytes key_id = 1; 27 | ErrorCode code = 2; 28 | } 29 | 30 | message PublicKeyRequest { 31 | bytes key_id = 1; 32 | } 33 | 34 | message PublicKeyResponse { 35 | bytes public_key = 1; 36 | ErrorCode code = 2; 37 | } 38 | 39 | message SignRequest { 40 | bytes key_id = 1; 41 | // message_hash should be a prehashed message of length crypto::HashValue::LENGTH = 32 bytes 42 | bytes message_hash = 2; 43 | } 44 | 45 | message SignResponse { 46 | bytes signature = 1; 47 | ErrorCode code = 2; 48 | } 49 | 50 | enum ErrorCode { 51 | Success = 0; 52 | KeyIdNotFound = 1; 53 | WrongLength = 2; 54 | InvalidParameters = 3; 55 | AuthenticationFailed = 4; 56 | Unspecified = 5; 57 | 58 | // Good examples of more error codes: https://developers.yubico.com/YubiHSM2/Component_Reference/KSP/Status_codes.html 59 | } 60 | 61 | enum KeyType { 62 | Ed25519 = 0; 63 | BLS12381 = 1; 64 | } 65 | -------------------------------------------------------------------------------- /protofiles/lc/state_synchronizer.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package network; 7 | 8 | import "ledger_info.proto"; 9 | import "transaction.proto"; 10 | 11 | message GetChunkRequest { 12 | uint64 known_version = 1; 13 | uint64 limit = 2; 14 | uint64 timeout = 3; 15 | types.LedgerInfoWithSignatures ledger_info_with_sigs = 4; 16 | } 17 | 18 | message GetChunkResponse { 19 | types.LedgerInfoWithSignatures ledger_info_with_sigs = 1; 20 | // chunk of transactions with proof corresponding to version in `ledger_info_with_sigs` 21 | types.TransactionListWithProof txn_list_with_proof = 2; 22 | } 23 | 24 | message StateSynchronizerMsg { 25 | oneof message { 26 | GetChunkRequest chunk_request = 1; 27 | GetChunkResponse chunk_response = 2; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /protofiles/lc/storage.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package storage; 7 | 8 | import "get_with_proof.proto"; 9 | import "ledger_info.proto"; 10 | import "transaction.proto"; 11 | import "account_state_blob.proto"; 12 | import "proof.proto"; 13 | 14 | // ----------------------------------------------------------------------------- 15 | // ---------------- Service definition for storage 16 | // ----------------------------------------------------------------------------- 17 | service Storage { 18 | // Write APIs. 19 | 20 | // Persist transactions. Called by Execution when either syncing nodes or 21 | // committing blocks during normal operation. 22 | rpc SaveTransactions(SaveTransactionsRequest) 23 | returns (SaveTransactionsResponse); 24 | 25 | // Read APIs. 26 | 27 | // Used to get a piece of data and return the proof of it. If the client 28 | // knows and trusts a ledger info at version v, it should pass v in as the 29 | // client_known_version and we will return the latest ledger info together 30 | // with the proof that it derives from v. 31 | rpc UpdateToLatestLedger( 32 | types.UpdateToLatestLedgerRequest) 33 | returns (types.UpdateToLatestLedgerResponse); 34 | 35 | // When we receive a request from a peer validator asking a list of 36 | // transactions for state synchronization, this API can be used to serve the 37 | // request. Note that the peer should specify a ledger version and all proofs 38 | // in the response will be relative to this given ledger version. 39 | rpc GetTransactions(GetTransactionsRequest) returns (GetTransactionsResponse); 40 | 41 | rpc GetAccountStateWithProofByVersion( 42 | GetAccountStateWithProofByVersionRequest) 43 | returns (GetAccountStateWithProofByVersionResponse); 44 | 45 | // Returns information needed for libra core to start up. 46 | rpc GetStartupInfo(GetStartupInfoRequest) 47 | returns (GetStartupInfoResponse); 48 | } 49 | 50 | message SaveTransactionsRequest { 51 | // Transactions to persist. 52 | repeated types.TransactionToCommit txns_to_commit = 1; 53 | 54 | // The version of the first transaction in `txns_to_commit`. 55 | uint64 first_version = 2; 56 | 57 | // If this is set, Storage will check its state after applying the above 58 | // transactions matches info in this LedgerInfo before committing otherwise 59 | // it denies the request. 60 | types.LedgerInfoWithSignatures ledger_info_with_signatures = 3; 61 | } 62 | 63 | message SaveTransactionsResponse {} 64 | 65 | message GetTransactionsRequest { 66 | // The version to start with. 67 | uint64 start_version = 1; 68 | // The size of the transaction batch. 69 | uint64 batch_size = 2; 70 | // All the proofs returned in the response should be relative to this 71 | // given version. 72 | uint64 ledger_version = 3; 73 | // Used to return the events associated with each transaction 74 | bool fetch_events = 4; 75 | } 76 | 77 | message GetTransactionsResponse { 78 | types.TransactionListWithProof txn_list_with_proof = 1; 79 | } 80 | 81 | message GetAccountStateWithProofByVersionRequest { 82 | /// The account address to query with. 83 | bytes address = 1; 84 | 85 | /// The version the query is based on. 86 | uint64 version = 2; 87 | } 88 | 89 | message GetAccountStateWithProofByVersionResponse { 90 | /// The optional blob of account state blob. 91 | types.AccountStateBlob account_state_blob = 1; 92 | 93 | /// The state root hash the query is based on. 94 | types.SparseMerkleProof sparse_merkle_proof = 2; 95 | } 96 | 97 | message GetStartupInfoRequest {} 98 | 99 | message GetStartupInfoResponse { 100 | // When this is empty, Storage needs to be bootstrapped via the bootstrap API 101 | StartupInfo info = 1; 102 | } 103 | 104 | message StartupInfo { 105 | // The latest LedgerInfo. Note that at start up storage can have more 106 | // transactions than the latest LedgerInfo indicates due to an incomplete 107 | // start up sync. 108 | types.LedgerInfo ledger_info = 1; 109 | // The latest version. All fields below are based on this version. 110 | uint64 latest_version = 2; 111 | // The latest account state root hash. 112 | bytes account_state_root_hash = 3; 113 | // From left to right, root hashes of all frozen subtrees. 114 | repeated bytes ledger_frozen_subtree_hashes = 4; 115 | } 116 | -------------------------------------------------------------------------------- /protofiles/lc/test.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package test; 7 | 8 | message Int32 { int32 value = 1; } 9 | 10 | message Int64 { int64 value = 1; } 11 | 12 | message UInt32 { uint32 value = 1; } 13 | 14 | message UInt64 { uint64 value = 1; } 15 | 16 | message SInt32 { sint32 value = 1; } 17 | 18 | message SInt64 { sint64 value = 1; } 19 | 20 | message Fixed32 { fixed32 value = 1; } 21 | 22 | message Fixed64 { fixed64 value = 1; } 23 | 24 | message Boolean { bool value = 1; } 25 | 26 | message Strings { string value = 1; } 27 | 28 | message Bytes { bytes value = 1; } 29 | 30 | message Repeated { repeated Int32 value = 1; } 31 | 32 | message Structs { 33 | Int32 a = 1; 34 | UInt32 b = 2; 35 | SInt32 c = 3; 36 | Fixed32 d = 4; 37 | Boolean e = 5; 38 | Strings f = 6; 39 | Bytes g = 7; 40 | repeated Int32 h = 8; 41 | } 42 | -------------------------------------------------------------------------------- /protofiles/lc/transaction.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | import "access_path.proto"; 9 | import "events.proto"; 10 | import "proof.proto"; 11 | import "transaction_info.proto"; 12 | import "google/protobuf/wrappers.proto"; 13 | 14 | // A generic structure that describes a transaction that a client submits 15 | message RawTransaction { 16 | // Sender's account address 17 | bytes sender_account = 1; 18 | // Sequence number of this transaction corresponding to sender's account. 19 | uint64 sequence_number = 2; 20 | oneof payload { 21 | // The transaction script to execute. 22 | Program program = 3; 23 | // A write set, used for genesis blocks and other magic transactions. 24 | // This bypasses the rules for regular transactions so will typically be 25 | // rejected. Only under special circumstances will it be accepted. 26 | WriteSet write_set = 4; 27 | // The transaction script to execute. 28 | Script script = 8; 29 | // The MOVE Module to publish. 30 | Module module = 9; 31 | } 32 | // Maximal total gas specified by wallet to spend for this transaction. 33 | uint64 max_gas_amount = 5; 34 | // The price to be paid for each unit of gas. 35 | uint64 gas_unit_price = 6; 36 | // Expiration time for this transaction. If storage is queried and 37 | // the time returned is greater than or equal to this time and this 38 | // transaction has not been included, you can be certain that it will 39 | // never be included. 40 | // If set to 0, there will be no expiration time 41 | uint64 expiration_time = 7; 42 | } 43 | 44 | // The code for the transaction to execute 45 | message Program { 46 | bytes code = 1; 47 | repeated TransactionArgument arguments = 2; 48 | repeated bytes modules = 3; 49 | } 50 | 51 | // The code for the transaction to execute 52 | message Script { 53 | bytes code = 1; 54 | repeated TransactionArgument arguments = 2; 55 | } 56 | 57 | // An argument to the transaction if the transaction takes arguments 58 | message TransactionArgument { 59 | enum ArgType { 60 | U64 = 0; 61 | ADDRESS = 1; 62 | STRING = 2; 63 | BYTEARRAY = 3; 64 | } 65 | ArgType type = 1; 66 | bytes data = 2; 67 | } 68 | 69 | // A Move Module to publish 70 | message Module { 71 | bytes code = 1; 72 | } 73 | 74 | // A generic structure that represents signed RawTransaction 75 | message SignedTransaction { 76 | // The serialized Protobuf bytes for RawTransaction, for which the signature 77 | // was signed. Protobuf doesn't guarantee the serialized bytes is canonical 78 | // across different language implementations, but for our use cases for 79 | // transaction it is not necessary because the client is the only one to 80 | // produce this bytes, which is then persisted in storage. 81 | bytes raw_txn_bytes = 1; 82 | // public key that corresponds to RawTransaction::sender_account 83 | bytes sender_public_key = 2; 84 | // signature for the hash 85 | bytes sender_signature = 3; 86 | } 87 | 88 | message SignedTransactionWithProof { 89 | // The version of the returned signed transaction. 90 | uint64 version = 1; 91 | 92 | // The transaction itself. 93 | SignedTransaction signed_transaction = 2; 94 | 95 | // The proof authenticating the signed transaction. 96 | SignedTransactionProof proof = 3; 97 | 98 | // The events yielded by executing the transaction, if requested. 99 | EventsList events = 4; 100 | } 101 | 102 | // A generic structure that represents a block of transactions originated from a 103 | // particular validator instance. 104 | message SignedTransactionsBlock { 105 | // Set of Signed Transactions 106 | repeated SignedTransaction transactions = 1; 107 | // Public key of the validator that created this block 108 | bytes validator_public_key = 2; 109 | // Signature of the validator that created this block 110 | bytes validator_signature = 3; 111 | } 112 | 113 | // Set of WriteOps to save to storage. 114 | message WriteSet { 115 | // Set of WriteOp for storage update. 116 | repeated WriteOp write_set = 1; 117 | } 118 | 119 | // Write Operation on underlying storage. 120 | message WriteOp { 121 | // AccessPath of the write set. 122 | AccessPath access_path = 1; 123 | // The value of the write op. Empty if `type` is Delete. 124 | bytes value = 2; 125 | // WriteOp type. 126 | WriteOpType type = 3; 127 | } 128 | 129 | // Type of write operation 130 | enum WriteOpType { 131 | // The WriteOp is to create/update the field from storage. 132 | Write = 0; 133 | // The WriteOp is to delete the field from storage. 134 | Delete = 1; 135 | } 136 | 137 | // Account state as a whole. 138 | // After execution, updates to accounts are passed in this form to storage for 139 | // persistence. 140 | message AccountState { 141 | // Account address 142 | bytes address = 1; 143 | // Account state blob 144 | bytes blob = 2; 145 | } 146 | 147 | // Transaction struct to commit to storage 148 | message TransactionToCommit { 149 | // The signed transaction which was executed 150 | SignedTransaction signed_txn = 1; 151 | // State db updates 152 | repeated AccountState account_states = 2; 153 | // Events yielded by the transaction. 154 | repeated Event events = 3; 155 | // The amount of gas used. 156 | uint64 gas_used = 4; 157 | } 158 | 159 | // A list of consecutive transactions with proof. This is mainly used for state 160 | // synchronization when a validator would request a list of transactions from a 161 | // peer, verify the proof, execute the transactions and persist them. Note that 162 | // the transactions are supposed to belong to the same epoch E, otherwise 163 | // verification will fail. 164 | message TransactionListWithProof { 165 | // The list of transactions. 166 | repeated SignedTransaction transactions = 1; 167 | 168 | // The list of corresponding TransactionInfo objects. 169 | repeated TransactionInfo infos = 2; 170 | 171 | // The list of corresponding Event objects (only present if fetch_events was set to true in req) 172 | EventsForVersions events_for_versions = 3; 173 | 174 | // If the list is not empty, the version of the first transaction. 175 | google.protobuf.UInt64Value first_transaction_version = 4; 176 | 177 | // The proofs of the first and last transaction in this chunk. When this is 178 | // used for state synchronization, the validator who requests the transactions 179 | // will provide a version in the request and the proofs will be relative to 180 | // the given version. When this is returned in GetTransactionsResponse, the 181 | // proofs will be relative to the ledger info returned in 182 | // UpdateToLatestLedgerResponse. 183 | AccumulatorProof proof_of_first_transaction = 5; 184 | AccumulatorProof proof_of_last_transaction = 6; 185 | } 186 | -------------------------------------------------------------------------------- /protofiles/lc/transaction_info.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | // `TransactionInfo` is the object we store in the transaction accumulator. It 9 | // consists of the transaction as well as the execution result of this 10 | // transaction. This are later returned to the client so that a client can 11 | // validate the tree 12 | message TransactionInfo { 13 | // Hash of the signed transaction that is stored 14 | bytes signed_transaction_hash = 1; 15 | 16 | // The root hash of Sparse Merkle Tree describing the world state at the end 17 | // of this transaction 18 | bytes state_root_hash = 2; 19 | 20 | // The root hash of Merkle Accumulator storing all events emitted during this 21 | // transaction. 22 | bytes event_root_hash = 3; 23 | 24 | // The amount of gas used by this transaction. 25 | uint64 gas_used = 4; 26 | } 27 | -------------------------------------------------------------------------------- /protofiles/lc/validator_change.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | import "events.proto"; 9 | import "ledger_info.proto"; 10 | 11 | // This is used to prove validator changes. When a validator is changing, it 12 | // triggers an event on /validator_change_account/events/sent. To tell the 13 | // client about validator changes, we query 14 | // /validator_change_account/events/sent to get all versions that contain 15 | // validator changes after the version that we are trying to update from. For 16 | // each of these versions, the old validator set would have signed the ledger 17 | // info at that version. The client needs this as well as the event results + 18 | // proof. The client can then verify that these events were under the current 19 | // tree and that the changes were signed by the old validators (and that the 20 | // events correctly show which validators are the new validators). 21 | // 22 | // This message represents a single validator change event and the proof that 23 | // corresponds to it 24 | message ValidatorChangeEventWithProof { 25 | LedgerInfoWithSignatures ledger_info_with_sigs = 1; 26 | EventWithProof event_with_proof = 2; 27 | } 28 | -------------------------------------------------------------------------------- /protofiles/lc/validator_public_keys.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | // Protobuf definition for the Rust struct ValidatorPublicKeys 9 | message ValidatorPublicKeys { 10 | // Validator account address 11 | bytes account_address = 1; 12 | // Consensus public key 13 | bytes consensus_public_key = 2; 14 | // Network signing publick key 15 | bytes network_signing_public_key = 3; 16 | /// Network identity publick key 17 | bytes network_identity_public_key = 4; 18 | } 19 | -------------------------------------------------------------------------------- /protofiles/lc/validator_set.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | import "validator_public_keys.proto"; 9 | 10 | // Protobuf definition for the Rust struct ValidatorSet. 11 | message ValidatorSet { 12 | repeated ValidatorPublicKeys validator_public_keys = 1; 13 | } 14 | -------------------------------------------------------------------------------- /protofiles/lc/vm_errors.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) The Libra Core Contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package types; 7 | 8 | import "language_storage.proto"; 9 | 10 | // The statuses and errors produced by the VM can be categorized into a 11 | // couple different types: 12 | // 1. Validation Statuses: all the errors that can (/should) be 13 | // the result of executing the prologue -- these are primarily used by 14 | // the vm validator and AC. 15 | // 2. Verification Errors: errors that are the result of performing 16 | // bytecode verification (happens at the time of publishing). 17 | // 3. VM Invariant Errors: errors that arise from an internal invariant of 18 | // the VM being violated. These signify a problem with either the VM or 19 | // bytecode verifier. 20 | // 4. Binary Errors: errors that can occur during the process of 21 | // deserialization of a transaction. 22 | // 5. Runtime Statuses: errors that can arise from the execution of a 23 | // transaction (assuming the prologue executes without error). These are 24 | // errors that can occur during execution due to things such as division 25 | // by zero, running out of gas, etc. These do not signify an issue with 26 | // the VM. 27 | 28 | // NB: we make a distinction between a status and an error here: A 29 | // status contains errors, along with possible affirmation of a successful 30 | // execution or valid prologue. 31 | 32 | // The status of a transaction as determined by the prologue. 33 | enum VMValidationStatusCode { 34 | // We don't want the default value to be valid 35 | UnknownValidationStatus = 0; 36 | // The transaction has a bad signature 37 | InvalidSignature = 1; 38 | // Bad account authentication key 39 | InvalidAuthKey = 2; 40 | // Sequence number is too old 41 | SequenceNumberTooOld = 3; 42 | // Sequence number is too new 43 | SequenceNumberTooNew = 4; 44 | // Insufficient balance to pay minimum transaction fee 45 | InsufficientBalanceForTransactionFee = 5; 46 | // The transaction has expired 47 | TransactionExpired = 6; 48 | // The sending account does not exist 49 | SendingAccountDoesNotExist = 7; 50 | // This write set transaction was rejected because it did not meet the 51 | // requirements for one. 52 | RejectedWriteSet = 8; 53 | // This write set transaction cannot be applied to the current state. 54 | InvalidWriteSet = 9; 55 | // Length of program field in raw transaction exceeded max length 56 | ExceededMaxTransactionSize = 10; 57 | // This script is not on our whitelist of script. 58 | UnknownScript = 11; 59 | // Transaction is trying to publish a new module. 60 | UnknownModule = 12; 61 | // Max gas units submitted with transaction exceeds max gas units bound 62 | // in VM 63 | MaxGasUnitsExceedsMaxGasUnitsBound = 13; 64 | // Max gas units submitted with transaction not enough to cover the 65 | // intrinsic cost of the transaction. 66 | MaxGasUnitsBelowMinTransactionGasUnits = 14; 67 | // Gas unit price submitted with transaction is below minimum gas price 68 | // set in the VM. 69 | GasUnitPriceBelowMinBound = 15; 70 | // Gas unit price submitted with the transaction is above the maximum 71 | // gas price set in the VM. 72 | GasUnitPriceAboveMaxBound = 16; 73 | } 74 | 75 | message VMValidationStatus { 76 | VMValidationStatusCode code = 1; 77 | string message = 2; 78 | } 79 | 80 | message VMVerificationStatusList { 81 | repeated VMVerificationStatus status_list = 1; 82 | } 83 | 84 | message VMVerificationStatus { 85 | enum StatusKind { 86 | SCRIPT = 0; 87 | MODULE = 1; 88 | DEPENDENCY = 2; 89 | } 90 | StatusKind status_kind = 1; 91 | // For StatusKind::SCRIPT and DEPENDENCY this is ignored. 92 | uint32 module_idx = 2; 93 | VMVerificationErrorKind error_kind = 3; 94 | string message = 4; 95 | // For StatusKind::SCRIPT and MODULE this is ignored. 96 | ModuleId dependency_id = 5; 97 | } 98 | 99 | // When a code module/script is published it is verified. These are the 100 | // possible errors that can arise from the verification process. 101 | enum VMVerificationErrorKind { 102 | // Likewise default to a unknown verification error 103 | UnknownVerificationError = 0; 104 | IndexOutOfBounds = 1; 105 | CodeUnitIndexOutOfBounds = 2; 106 | RangeOutOfBounds = 3; 107 | InvalidSignatureToken = 4; 108 | InvalidFieldDefReference = 5; 109 | RecursiveStructDefinition = 6; 110 | InvalidResourceField = 7; 111 | InvalidFallThrough = 8; 112 | JoinFailure = 9; 113 | NegativeStackSizeWithinBlock = 10; 114 | UnbalancedStack = 11; 115 | InvalidMainFunctionSignature = 12; 116 | DuplicateElement = 13; 117 | InvalidModuleHandle = 14; 118 | UnimplementedHandle = 15; 119 | InconsistentFields = 16; 120 | UnusedFields = 17; 121 | LookupFailed = 18; 122 | VisibilityMismatch = 19; 123 | TypeResolutionFailure = 20; 124 | TypeMismatch = 21; 125 | MissingDependency = 22; 126 | PopReferenceError = 23; 127 | PopResourceError = 24; 128 | ReleaseRefTypeMismatchError = 25; 129 | BrTypeMismatchError = 26; 130 | AbortTypeMismatchError = 27; 131 | StLocTypeMismatchError = 28; 132 | StLocUnsafeToDestroyError = 29; 133 | RetUnsafeToDestroyError = 30; 134 | RetTypeMismatchError = 31; 135 | FreezeRefTypeMismatchError = 32; 136 | FreezeRefExistsMutableBorrowError = 33; 137 | BorrowFieldTypeMismatchError = 34; 138 | BorrowFieldBadFieldError = 35; 139 | BorrowFieldExistsMutableBorrowError = 36; 140 | CopyLocUnavailableError = 37; 141 | CopyLocResourceError = 38; 142 | CopyLocExistsBorrowError = 39; 143 | MoveLocUnavailableError = 40; 144 | MoveLocExistsBorrowError = 41; 145 | BorrowLocReferenceError = 42; 146 | BorrowLocUnavailableError = 43; 147 | BorrowLocExistsBorrowError = 44; 148 | CallTypeMismatchError = 45; 149 | CallBorrowedMutableReferenceError = 46; 150 | PackTypeMismatchError = 47; 151 | UnpackTypeMismatchError = 48; 152 | ReadRefTypeMismatchError = 49; 153 | ReadRefResourceError = 50; 154 | ReadRefExistsMutableBorrowError = 51; 155 | WriteRefTypeMismatchError = 52; 156 | WriteRefResourceError = 53; 157 | WriteRefExistsBorrowError = 54; 158 | WriteRefNoMutableReferenceError = 55; 159 | IntegerOpTypeMismatchError = 56; 160 | BooleanOpTypeMismatchError = 57; 161 | EqualityOpTypeMismatchError = 58; 162 | ExistsResourceTypeMismatchError = 59; 163 | ExistsNoResourceError = 60; 164 | BorrowGlobalTypeMismatchError = 61; 165 | BorrowGlobalNoResourceError = 62; 166 | MoveFromTypeMismatchError = 63; 167 | MoveFromNoResourceError = 64; 168 | MoveToSenderTypeMismatchError = 65; 169 | MoveToSenderNoResourceError = 66; 170 | CreateAccountTypeMismatchError = 67; 171 | GlobalReferenceError = 68; 172 | // The self address of a module the transaction is publishing is not the sender address 173 | ModuleAddressDoesNotMatchSender = 69; 174 | // The module does not have any module handles. Each module or script must have at least one module handle. 175 | NoModuleHandles = 70; 176 | MissingAcquiresResourceAnnotationError = 71; 177 | ExtraneousAcquiresResourceAnnotationError = 72; 178 | DuplicateAcquiresResourceAnnotationError = 73; 179 | InvalidAcquiresResourceAnnotationError = 74; 180 | } 181 | 182 | // These are errors that the VM might raise if a violation of internal 183 | // invariants takes place. 184 | enum VMInvariantViolationError { 185 | UnknownInvariantViolationError = 0; 186 | OutOfBoundsIndex = 1; 187 | OutOfBoundsRange = 2; 188 | EmptyValueStack = 3; 189 | EmptyCallStack = 4; 190 | PCOverflow = 5; 191 | LinkerError = 6; 192 | LocalReferenceError = 7; 193 | StorageError = 8; 194 | InternalTypeError = 9; 195 | EventKeyMismatch = 10; 196 | } 197 | 198 | // Errors that can arise from binary decoding (deserialization) 199 | enum BinaryError { 200 | UnknownBinaryError = 0; 201 | Malformed = 1; 202 | BadMagic = 2; 203 | UnknownVersion = 3; 204 | UnknownTableType = 4; 205 | UnknownSignatureType = 5; 206 | UnknownSerializedType = 6; 207 | UnknownOpcode = 7; 208 | BadHeaderTable = 8; 209 | UnexpectedSignatureType = 9; 210 | DuplicateTable = 10; 211 | } 212 | 213 | //************************* 214 | // Runtime errors/status 215 | //************************* 216 | 217 | enum RuntimeStatus { 218 | UnknownRuntimeStatus = 0; 219 | Executed = 1; 220 | OutOfGas = 2; 221 | // We tried to access a resource that does not exist under the account. 222 | ResourceDoesNotExist = 3; 223 | // We tried to create a resource under an account where that resource 224 | // already exists. 225 | ResourceAlreadyExists = 4; 226 | // We accessed an account that is evicted. 227 | EvictedAccountAccess = 5; 228 | // We tried to create an account at an address where an account already 229 | // exists. 230 | AccountAddressAlreadyExists = 6; 231 | TypeError = 7; 232 | MissingData = 8; 233 | DataFormatError = 9; 234 | InvalidData = 10; 235 | RemoteDataError = 11; 236 | CannotWriteExistingResource = 12; 237 | ValueSerializationError = 13; 238 | ValueDeserializationError = 14; 239 | // The sender is trying to publish a module named `M`, but the sender's account already contains 240 | // a module with this name. 241 | DuplicateModuleName = 15; 242 | } 243 | 244 | // user-defined abort error code number 245 | message Aborted { 246 | uint64 aborted_error_code = 1; 247 | } 248 | 249 | message ArithmeticError { 250 | enum ArithmeticErrorType { 251 | UnknownArithmeticError = 0; 252 | Underflow = 1; 253 | Overflow = 2; 254 | DivisionByZero = 3; 255 | // Fill with more later 256 | } 257 | ArithmeticErrorType error_code = 1; 258 | } 259 | 260 | message DynamicReferenceError { 261 | enum DynamicReferenceErrorType { 262 | UnknownDynamicReferenceError = 0; 263 | MoveOfBorrowedResource = 1; 264 | GlobalRefAlreadyReleased = 2; 265 | MissingReleaseRef = 3; 266 | GlobalAlreadyBorrowed = 4; 267 | // Fill with with more later 268 | } 269 | DynamicReferenceErrorType error_code = 1; 270 | } 271 | 272 | message ExecutionStatus { 273 | oneof execution_status { 274 | RuntimeStatus runtime_status = 1; 275 | Aborted aborted = 2; 276 | ArithmeticError arithmetic_error = 3; 277 | DynamicReferenceError reference_error = 4; 278 | } 279 | } 280 | 281 | // The status of the VM 282 | message VMStatus { 283 | oneof error_type { 284 | VMValidationStatus validation = 1; 285 | VMVerificationStatusList verification = 2; 286 | VMInvariantViolationError invariant_violation = 3; 287 | BinaryError deserialization = 4; 288 | ExecutionStatus execution = 5; 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /protofiles/trillian/trillian.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | option java_multiple_files = true; 18 | option java_package = "com.google.trillian.proto"; 19 | option java_outer_classname = "TrillianProto"; 20 | option go_package = "github.com/google/trillian"; 21 | 22 | package trillian; 23 | 24 | import "crypto/keyspb/keyspb.proto"; 25 | import "crypto/sigpb/sigpb.proto"; 26 | import "google/protobuf/any.proto"; 27 | import "google/protobuf/duration.proto"; 28 | import "google/protobuf/timestamp.proto"; 29 | 30 | 31 | // LogRootFormat specifies the fields that are covered by the 32 | // SignedLogRoot signature, as well as their ordering and formats. 33 | enum LogRootFormat { 34 | LOG_ROOT_FORMAT_UNKNOWN = 0; 35 | LOG_ROOT_FORMAT_V1 = 1; 36 | } 37 | 38 | // MapRootFormat specifies the fields that are covered by the 39 | // SignedMapRoot signature, as well as their ordering and formats. 40 | enum MapRootFormat { 41 | MAP_ROOT_FORMAT_UNKNOWN = 0; 42 | MAP_ROOT_FORMAT_V1 = 1; 43 | } 44 | 45 | 46 | // What goes in here? 47 | // Things which are exposed through the public trillian APIs. 48 | 49 | // Defines the way empty / node / leaf hashes are constructed incorporating 50 | // preimage protection, which can be application specific. 51 | enum HashStrategy { 52 | // Hash strategy cannot be determined. Included to enable detection of 53 | // mismatched proto versions being used. Represents an invalid value. 54 | UNKNOWN_HASH_STRATEGY = 0; 55 | 56 | // Certificate Transparency strategy: leaf hash prefix = 0x00, node prefix = 57 | // 0x01, empty hash is digest([]byte{}), as defined in the specification. 58 | RFC6962_SHA256 = 1; 59 | 60 | // Sparse Merkle Tree strategy: leaf hash prefix = 0x00, node prefix = 0x01, 61 | // empty branch is recursively computed from empty leaf nodes. 62 | // NOT secure in a multi tree environment. For testing only. 63 | TEST_MAP_HASHER = 2; 64 | 65 | // Append-only log strategy where leaf nodes are defined as the ObjectHash. 66 | // All other properties are equal to RFC6962_SHA256. 67 | OBJECT_RFC6962_SHA256 = 3; 68 | 69 | // The CONIKS sparse tree hasher with SHA512_256 as the hash algorithm. 70 | CONIKS_SHA512_256 = 4; 71 | 72 | // The CONIKS sparse tree hasher with SHA256 as the hash algorithm. 73 | CONIKS_SHA256 = 5; 74 | } 75 | 76 | // State of the tree. 77 | enum TreeState { 78 | // Tree state cannot be determined. Included to enable detection of 79 | // mismatched proto versions being used. Represents an invalid value. 80 | UNKNOWN_TREE_STATE = 0; 81 | 82 | // Active trees are able to respond to both read and write requests. 83 | ACTIVE = 1; 84 | 85 | // Frozen trees are only able to respond to read requests, writing to a frozen 86 | // tree is forbidden. Trees should not be frozen when there are entries 87 | // in the queue that have not yet been integrated. See the DRAINING 88 | // state for this case. 89 | FROZEN = 2; 90 | 91 | // Deprecated: now tracked in Tree.deleted. 92 | DEPRECATED_SOFT_DELETED = 3 [deprecated = true]; 93 | 94 | // Deprecated: now tracked in Tree.deleted. 95 | DEPRECATED_HARD_DELETED = 4 [deprecated = true]; 96 | 97 | // A tree that is draining will continue to integrate queued entries. 98 | // No new entries should be accepted. 99 | DRAINING = 5; 100 | } 101 | 102 | // Type of the tree. 103 | enum TreeType { 104 | // Tree type cannot be determined. Included to enable detection of mismatched 105 | // proto versions being used. Represents an invalid value. 106 | UNKNOWN_TREE_TYPE = 0; 107 | 108 | // Tree represents a verifiable log. 109 | LOG = 1; 110 | 111 | // Tree represents a verifiable map. 112 | MAP = 2; 113 | 114 | // Tree represents a verifiable pre-ordered log, i.e., a log whose entries are 115 | // placed according to sequence numbers assigned outside of Trillian. 116 | PREORDERED_LOG = 3; 117 | } 118 | 119 | // Represents a tree, which may be either a verifiable log or map. 120 | // Readonly attributes are assigned at tree creation, after which they may not 121 | // be modified. 122 | // 123 | // Note: Many APIs within the rest of the code require these objects to 124 | // be provided. For safety they should be obtained via Admin API calls and 125 | // not created dynamically. 126 | message Tree { 127 | // ID of the tree. 128 | // Readonly. 129 | int64 tree_id = 1; 130 | 131 | // State of the tree. 132 | // Trees are ACTIVE after creation. At any point the tree may transition 133 | // between ACTIVE, DRAINING and FROZEN states. 134 | TreeState tree_state = 2; 135 | 136 | // Type of the tree. 137 | // Readonly after Tree creation. Exception: Can be switched from 138 | // PREORDERED_LOG to LOG if the Tree is and remains in the FROZEN state. 139 | TreeType tree_type = 3; 140 | 141 | // Hash strategy to be used by the tree. 142 | // Readonly. 143 | HashStrategy hash_strategy = 4; 144 | 145 | // Hash algorithm to be used by the tree. 146 | // Readonly. 147 | sigpb.DigitallySigned.HashAlgorithm hash_algorithm = 5; 148 | 149 | // Signature algorithm to be used by the tree. 150 | // Readonly. 151 | sigpb.DigitallySigned.SignatureAlgorithm signature_algorithm = 6; 152 | 153 | reserved 18; // Signature cipher suite (removed) 154 | reserved 7; // DuplicatePolicy (removed) 155 | 156 | // Display name of the tree. 157 | // Optional. 158 | string display_name = 8; 159 | 160 | // Description of the tree, 161 | // Optional. 162 | string description = 9; 163 | 164 | reserved 10; // create_time_millis_since_epoch (removed) 165 | reserved 11; // update_time_millis_since_epoch (removed) 166 | 167 | // Identifies the private key used for signing tree heads and entry 168 | // timestamps. 169 | // This can be any type of message to accommodate different key management 170 | // systems, e.g. PEM files, HSMs, etc. 171 | // Private keys are write-only: they're never returned by RPCs. 172 | // The private_key message can be changed after a tree is created, but the 173 | // underlying key must remain the same - this is to enable migrating a key 174 | // from one provider to another. 175 | google.protobuf.Any private_key = 12; 176 | 177 | // Storage-specific settings. 178 | // Varies according to the storage implementation backing Trillian. 179 | google.protobuf.Any storage_settings = 13; 180 | 181 | // The public key used for verifying tree heads and entry timestamps. 182 | // Readonly. 183 | keyspb.PublicKey public_key = 14; 184 | 185 | // Interval after which a new signed root is produced even if there have been 186 | // no submission. If zero, this behavior is disabled. 187 | google.protobuf.Duration max_root_duration = 15; 188 | 189 | // Time of tree creation. 190 | // Readonly. 191 | google.protobuf.Timestamp create_time = 16; 192 | 193 | // Time of last tree update. 194 | // Readonly (automatically assigned on updates). 195 | google.protobuf.Timestamp update_time = 17; 196 | 197 | // If true, the tree has been deleted. 198 | // Deleted trees may be undeleted during a certain time window, after which 199 | // they're permanently deleted (and unrecoverable). 200 | // Readonly. 201 | bool deleted = 19; 202 | 203 | // Time of tree deletion, if any. 204 | // Readonly. 205 | google.protobuf.Timestamp delete_time = 20; 206 | } 207 | 208 | message SignedEntryTimestamp { 209 | int64 timestamp_nanos = 1; 210 | int64 log_id = 2; 211 | sigpb.DigitallySigned signature = 3; 212 | } 213 | 214 | // SignedLogRoot represents a commitment by a Log to a particular tree. 215 | message SignedLogRoot { 216 | // Deprecated: TimestampNanos moved to LogRoot. 217 | int64 timestamp_nanos = 1; 218 | // Deprecated: RootHash moved to LogRoot. 219 | bytes root_hash = 2; 220 | // Deprecated: TreeSize moved to LogRoot. 221 | int64 tree_size = 3; 222 | // Deprecated: TreeRevision moved to LogRoot. 223 | int64 tree_revision = 6; 224 | 225 | // Deleted: Signature replaced by LogRootSignature. 226 | reserved 4; 227 | 228 | // Deleted: LogID is associated with the public key that validates signature. 229 | reserved 5; 230 | 231 | // key_hint is a hint to identify the public key for signature verification. 232 | // key_hint is not authenticated and may be incorrect or missing, in which 233 | // case all known public keys may be used to verify the signature. 234 | // When directly communicating with a Trillian gRPC server, the key_hint will 235 | // typically contain the LogID encoded as a big-endian 64-bit integer; 236 | // however, in other contexts the key_hint is likely to have different 237 | // contents (e.g. it could be a GUID, a URL + TreeID, or it could be 238 | // derived from the public key itself). 239 | bytes key_hint = 7; 240 | 241 | // log_root holds the TLS-serialization of the following structure (described 242 | // in RFC5246 notation): Clients should validate log_root_signature with 243 | // VerifySignedLogRoot before deserializing log_root. 244 | // enum { v1(1), (65535)} Version; 245 | // struct { 246 | // uint64 tree_size; 247 | // opaque root_hash<0..128>; 248 | // uint64 timestamp_nanos; 249 | // uint64 revision; 250 | // opaque metadata<0..65535>; 251 | // } LogRootV1; 252 | // struct { 253 | // Version version; 254 | // select(version) { 255 | // case v1: LogRootV1; 256 | // } 257 | // } LogRoot; 258 | bytes log_root = 8; 259 | 260 | // log_root_signature is the raw signature over log_root. 261 | bytes log_root_signature = 9; 262 | } 263 | 264 | // SignedMapRoot represents a commitment by a Map to a particular tree. 265 | message SignedMapRoot { 266 | reserved 1; // Deprecated: Was timestamp_nanos. Use map_root. 267 | reserved 2; // Deprecated: Was root_hash. Use map_root. 268 | reserved 3; // Deprecated: Was MapperMetadata. Use map_root. 269 | reserved 5; // Deprecated: Was map_id. Use signature. 270 | reserved 6; // Deprecated: Was map_revision. Use map_root. 271 | reserved 7; // Deprecated: Was metadata Any. Use map_root. 272 | reserved 8; // Deprecated: Was metadata bytes. Use map_root. 273 | 274 | // map_root holds the TLS-serialization of the following structure (described 275 | // in RFC5246 notation): Clients should validate signature with 276 | // VerifySignedMapRoot before deserializing map_root. 277 | // enum { v1(1), (65535)} Version; 278 | // struct { 279 | // opaque root_hash<0..128>; 280 | // uint64 timestamp_nanos; 281 | // uint64 revision; 282 | // opaque metadata<0..65535>; 283 | // } MapRootV1; 284 | // struct { 285 | // Version version; 286 | // select(version) { 287 | // case v1: MapRootV1; 288 | // } 289 | // } MapRoot; 290 | bytes map_root = 9; 291 | // Signature is the raw signature over MapRoot. 292 | bytes signature = 4; 293 | } 294 | -------------------------------------------------------------------------------- /protofiles/trillian/trillian_admin_api.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | option java_multiple_files = true; 18 | option java_package = "com.google.trillian.proto"; 19 | option java_outer_classname = "TrillianAdminApiProto"; 20 | option go_package = "github.com/google/trillian"; 21 | 22 | package trillian; 23 | 24 | import "trillian.proto"; 25 | import "crypto/keyspb/keyspb.proto"; 26 | import "google/api/annotations.proto"; 27 | import "google/protobuf/field_mask.proto"; 28 | 29 | // ListTrees request. 30 | // No filters or pagination options are provided. 31 | message ListTreesRequest { 32 | // If true, deleted trees are included in the response. 33 | bool show_deleted = 1; 34 | } 35 | 36 | // ListTrees response. 37 | // No pagination is provided, all trees the requester has access to are 38 | // returned. 39 | message ListTreesResponse { 40 | // Trees matching the list request filters. 41 | repeated Tree tree = 1; 42 | } 43 | 44 | // GetTree request. 45 | message GetTreeRequest { 46 | // ID of the tree to retrieve. 47 | int64 tree_id = 1; 48 | } 49 | 50 | // CreateTree request. 51 | message CreateTreeRequest { 52 | // Tree to be created. See Tree and CreateTree for more details. 53 | Tree tree = 1; 54 | 55 | // Describes how the tree's private key should be generated. 56 | // Only needs to be set if tree.private_key is not set. 57 | keyspb.Specification key_spec = 2; 58 | } 59 | 60 | // UpdateTree request. 61 | message UpdateTreeRequest { 62 | // Tree to be updated. 63 | Tree tree = 1; 64 | 65 | // Fields modified by the update request. 66 | // For example: "tree_state", "display_name", "description". 67 | google.protobuf.FieldMask update_mask = 2; 68 | } 69 | 70 | // DeleteTree request. 71 | message DeleteTreeRequest { 72 | // ID of the tree to delete. 73 | int64 tree_id = 1; 74 | } 75 | 76 | // UndeleteTree request. 77 | message UndeleteTreeRequest { 78 | // ID of the tree to undelete. 79 | int64 tree_id = 1; 80 | } 81 | 82 | // Trillian Administrative interface. 83 | // Allows creation and management of Trillian trees (both log and map trees). 84 | service TrillianAdmin { 85 | // Lists all trees the requester has access to. 86 | rpc ListTrees(ListTreesRequest) returns(ListTreesResponse) {} 87 | 88 | // Retrieves a tree by ID. 89 | rpc GetTree(GetTreeRequest) returns(Tree) { 90 | option (google.api.http) = { 91 | get: "/v1beta1/trees/{tree_id=*}" 92 | }; 93 | } 94 | 95 | // Creates a new tree. 96 | // System-generated fields are not required and will be ignored if present, 97 | // e.g.: tree_id, create_time and update_time. 98 | // Returns the created tree, with all system-generated fields assigned. 99 | rpc CreateTree(CreateTreeRequest) returns(Tree) { 100 | option (google.api.http) = { 101 | post: "/v1beta1/trees" 102 | body: "*" 103 | }; 104 | } 105 | 106 | // Updates a tree. 107 | // See Tree for details. Readonly fields cannot be updated. 108 | rpc UpdateTree(UpdateTreeRequest) returns(Tree) { 109 | option (google.api.http) = { 110 | patch: "/v1beta1/trees/{tree.tree_id=*}" 111 | body: "*" 112 | }; 113 | } 114 | 115 | // Soft-deletes a tree. 116 | // A soft-deleted tree may be undeleted for a certain period, after which 117 | // it'll be permanently deleted. 118 | rpc DeleteTree(DeleteTreeRequest) returns(Tree) { 119 | option (google.api.http) = { 120 | delete: "/v1beta1/trees/{tree_id=*}" 121 | }; 122 | } 123 | 124 | // Undeletes a soft-deleted a tree. 125 | // A soft-deleted tree may be undeleted for a certain period, after which 126 | // it'll be permanently deleted. 127 | rpc UndeleteTree(UndeleteTreeRequest) returns(Tree) { 128 | option (google.api.http) = { 129 | delete: "/v1beta1/trees/{tree_id=*}:undelete" 130 | }; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /protofiles/trillian/trillian_log_api.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package trillian; 18 | 19 | option go_package = "github.com/google/trillian"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "TrillianLogApiProto"; 22 | option java_package = "com.google.trillian.proto"; 23 | 24 | import "google/api/annotations.proto"; 25 | import "google/protobuf/timestamp.proto"; 26 | import "google/rpc/status.proto"; 27 | import "trillian.proto"; 28 | 29 | // Provides access to a Verifiable Log data structure as defined in the 30 | // [Verifiable Data Structures](docs/papers/VerifiableDataStructures.pdf) paper. 31 | // 32 | // The API supports adding new entries to be integrated into the log's tree. It 33 | // does not provide arbitrary tree modifications. Additionally, it has read 34 | // operations such as obtaining tree leaves, inclusion/consistency proofs etc. 35 | service TrillianLog { 36 | // Adds a single leaf to the queue. 37 | rpc QueueLeaf (QueueLeafRequest) returns (QueueLeafResponse) { 38 | option (google.api.http) = { 39 | post: "/v1beta1/logs/{log_id}/leaves" 40 | body: "*" 41 | }; 42 | } 43 | 44 | // Adds a single leaf with an assigned sequence number. 45 | // Warning: This RPC is under development, don't use it. 46 | rpc AddSequencedLeaf (AddSequencedLeafRequest) returns (AddSequencedLeafResponse) { 47 | option (google.api.http) = { 48 | post: "/v1beta1/logs/{log_id}/leaves:sequenced" 49 | body: "*" 50 | }; 51 | } 52 | 53 | // 54 | // No direct equivalent at the storage level. 55 | // 56 | 57 | // Returns inclusion proof for a leaf with a given index in a given tree. 58 | rpc GetInclusionProof (GetInclusionProofRequest) returns (GetInclusionProofResponse) { 59 | option (google.api.http) = { 60 | get: "/v1beta1/logs/{log_id}/leaves/{leaf_index}:inclusion_proof" 61 | }; 62 | } 63 | // Returns inclusion proof for a leaf with a given identity hash in a given 64 | // tree. 65 | rpc GetInclusionProofByHash (GetInclusionProofByHashRequest) returns (GetInclusionProofByHashResponse) { 66 | option (google.api.http) = { 67 | get: "/v1beta1/logs/{log_id}/leaves:inclusion_by_hash" 68 | }; 69 | } 70 | // Returns consistency proof between two versions of a given tree. 71 | rpc GetConsistencyProof (GetConsistencyProofRequest) returns (GetConsistencyProofResponse) { 72 | option (google.api.http) = { 73 | get: "/v1beta1/logs/{log_id}:consistency_proof" 74 | }; 75 | } 76 | 77 | // Returns the latest signed log root for a given tree. Corresponds to the 78 | // ReadOnlyLogTreeTX.LatestSignedLogRoot storage interface. 79 | rpc GetLatestSignedLogRoot (GetLatestSignedLogRootRequest) returns (GetLatestSignedLogRootResponse) { 80 | option (google.api.http) = { 81 | get: "/v1beta1/logs/{log_id}/roots:latest" 82 | }; 83 | } 84 | 85 | // Returns the total number of leaves that have been integrated into the 86 | // given tree. Corresponds to the ReadOnlyLogTreeTX.GetSequencedLeafCount 87 | // storage interface. 88 | // DO NOT USE - FOR DEBUGGING/TEST ONLY 89 | rpc GetSequencedLeafCount (GetSequencedLeafCountRequest) returns (GetSequencedLeafCountResponse) { 90 | option (google.api.http) = { 91 | get: "/v1beta1/logs/{log_id}/leaves:sequenced_count" 92 | }; 93 | } 94 | 95 | // Returns log entry and the corresponding inclusion proof for a given leaf 96 | // index in a given tree. If the requested tree is unavailable but the leaf is in scope 97 | // for the current tree, return a proof in that tree instead. 98 | rpc GetEntryAndProof (GetEntryAndProofRequest) returns (GetEntryAndProofResponse) { 99 | option (google.api.http) = { 100 | get: "/v1beta1/logs/{log_id}/leaves/{leaf_index}" 101 | }; 102 | } 103 | 104 | // 105 | // Initialisation APIs. 106 | // 107 | 108 | rpc InitLog (InitLogRequest) returns (InitLogResponse) { 109 | option (google.api.http) = { 110 | post: "/v1beta1/logs/{log_id}:init" 111 | }; 112 | } 113 | 114 | // 115 | // Batch APIs. Correspond to `storage.ReadOnlyLogTreeTX` batch queries. 116 | // 117 | 118 | // Adds a batch of leaves to the queue. 119 | rpc QueueLeaves (QueueLeavesRequest) returns (QueueLeavesResponse) { 120 | } 121 | 122 | // Stores leaves from the provided batch and associates them with the log 123 | // positions according to the `LeafIndex` field. The indices must be 124 | // contiguous. 125 | // 126 | // Warning: This RPC is under development, don't use it. 127 | rpc AddSequencedLeaves (AddSequencedLeavesRequest) returns (AddSequencedLeavesResponse) { 128 | } 129 | 130 | // Returns a batch of leaves located in the provided positions. 131 | rpc GetLeavesByIndex (GetLeavesByIndexRequest) returns (GetLeavesByIndexResponse) { 132 | } 133 | // Returns a batch of leaves in a sequential range. 134 | rpc GetLeavesByRange (GetLeavesByRangeRequest) returns (GetLeavesByRangeResponse) { 135 | } 136 | // Returns a batch of leaves by their `merkle_leaf_hash` values. 137 | rpc GetLeavesByHash (GetLeavesByHashRequest) returns (GetLeavesByHashResponse) { 138 | } 139 | } 140 | 141 | // ChargeTo describes the user(s) associated with the request whose quota should 142 | // be checked and charged. 143 | message ChargeTo { 144 | // user is a list of personality-defined strings. 145 | // Trillian will treat them as /User/%{user}/... keys when checking and 146 | // charging quota. 147 | // If one or more of the specified users has insufficient quota, the 148 | // request will be denied. 149 | // 150 | // As an example, a Certificate Transparency frontend might set the following 151 | // user strings when sending a QueueLeaves request to the Trillian log: 152 | // - The requesting IP address. 153 | // This would limit the number of requests per IP. 154 | // - The "intermediate-" for each of the intermediate certificates in 155 | // the submitted chain. 156 | // This would have the effect of limiting the rate of submissions under 157 | // a given intermediate/root. 158 | repeated string user = 1; 159 | } 160 | 161 | message QueueLeafRequest { 162 | int64 log_id = 1; 163 | LogLeaf leaf = 2; 164 | ChargeTo charge_to = 3; 165 | } 166 | 167 | message QueueLeafResponse { 168 | QueuedLogLeaf queued_leaf = 2; 169 | } 170 | 171 | message AddSequencedLeafRequest { 172 | int64 log_id = 1; 173 | LogLeaf leaf = 2; 174 | ChargeTo charge_to = 3; 175 | } 176 | 177 | message AddSequencedLeafResponse { 178 | QueuedLogLeaf result = 2; 179 | } 180 | 181 | message GetInclusionProofRequest { 182 | int64 log_id = 1; 183 | int64 leaf_index = 2; 184 | int64 tree_size = 3; 185 | ChargeTo charge_to = 4; 186 | } 187 | 188 | message GetInclusionProofResponse { 189 | Proof proof = 2; 190 | SignedLogRoot signed_log_root = 3; 191 | } 192 | 193 | message GetInclusionProofByHashRequest { 194 | int64 log_id = 1; 195 | bytes leaf_hash = 2; 196 | int64 tree_size = 3; 197 | bool order_by_sequence = 4; 198 | ChargeTo charge_to = 5; 199 | } 200 | 201 | message GetInclusionProofByHashResponse { 202 | // Logs can potentially contain leaves with duplicate hashes so it's possible 203 | // for this to return multiple proofs. 204 | repeated Proof proof = 2; 205 | SignedLogRoot signed_log_root = 3; 206 | } 207 | 208 | message GetConsistencyProofRequest { 209 | int64 log_id = 1; 210 | int64 first_tree_size = 2; 211 | int64 second_tree_size = 3; 212 | ChargeTo charge_to = 4; 213 | } 214 | 215 | message GetConsistencyProofResponse { 216 | Proof proof = 2; 217 | SignedLogRoot signed_log_root = 3; 218 | } 219 | 220 | message GetLatestSignedLogRootRequest { 221 | int64 log_id = 1; 222 | ChargeTo charge_to = 2; 223 | } 224 | 225 | message GetLatestSignedLogRootResponse { 226 | SignedLogRoot signed_log_root = 2; 227 | } 228 | 229 | message GetSequencedLeafCountRequest { 230 | int64 log_id = 1; 231 | ChargeTo charge_to = 2; 232 | } 233 | 234 | message GetSequencedLeafCountResponse { 235 | int64 leaf_count = 2; 236 | } 237 | 238 | message GetEntryAndProofRequest { 239 | int64 log_id = 1; 240 | int64 leaf_index = 2; 241 | int64 tree_size = 3; 242 | ChargeTo charge_to = 4; 243 | } 244 | 245 | message GetEntryAndProofResponse { 246 | Proof proof = 2; 247 | LogLeaf leaf = 3; 248 | SignedLogRoot signed_log_root = 4; 249 | } 250 | 251 | message InitLogRequest { 252 | int64 log_id = 1; 253 | ChargeTo charge_to = 2; 254 | } 255 | 256 | message InitLogResponse { 257 | SignedLogRoot created = 1; 258 | } 259 | 260 | message QueueLeavesRequest { 261 | int64 log_id = 1; 262 | repeated LogLeaf leaves = 2; 263 | ChargeTo charge_to = 3; 264 | } 265 | 266 | message QueueLeavesResponse { 267 | // Same number and order as in the corresponding request. 268 | repeated QueuedLogLeaf queued_leaves = 2; 269 | } 270 | 271 | message AddSequencedLeavesRequest { 272 | int64 log_id = 1; 273 | repeated LogLeaf leaves = 2; 274 | ChargeTo charge_to = 4; 275 | } 276 | 277 | message AddSequencedLeavesResponse { 278 | // Same number and order as in the corresponding request. 279 | repeated QueuedLogLeaf results = 2; 280 | } 281 | 282 | message GetLeavesByIndexRequest { 283 | int64 log_id = 1; 284 | repeated int64 leaf_index = 2; 285 | ChargeTo charge_to = 5; 286 | } 287 | 288 | message GetLeavesByIndexResponse { 289 | // TODO(gbelvin) reply with error codes. Reuse QueuedLogLeaf? 290 | repeated LogLeaf leaves = 2; 291 | SignedLogRoot signed_log_root = 3; 292 | } 293 | 294 | message GetLeavesByRangeRequest { 295 | int64 log_id = 1; 296 | int64 start_index = 2; 297 | int64 count = 3; 298 | ChargeTo charge_to = 4; 299 | } 300 | 301 | message GetLeavesByRangeResponse { 302 | // Returned log leaves starting from the `start_index` of the request, in 303 | // order. There may be fewer than `request.count` leaves returned, if the 304 | // requested range extended beyond the size of the tree or if the server opted 305 | // to return fewer leaves than requested. 306 | repeated LogLeaf leaves = 1; 307 | SignedLogRoot signed_log_root = 2; 308 | } 309 | 310 | message GetLeavesByHashRequest { 311 | int64 log_id = 1; 312 | repeated bytes leaf_hash = 2; 313 | bool order_by_sequence = 3; 314 | ChargeTo charge_to = 5; 315 | } 316 | 317 | message GetLeavesByHashResponse { 318 | // TODO(gbelvin) reply with error codes. Reuse QueuedLogLeaf? 319 | repeated LogLeaf leaves = 2; 320 | SignedLogRoot signed_log_root = 3; 321 | } 322 | 323 | // A result of submitting an entry to the log. Output only. 324 | // TODO(pavelkalinnikov): Consider renaming it to AddLogLeafResult or the like. 325 | message QueuedLogLeaf { 326 | // The leaf as it was stored by Trillian. Empty unless `status.code` is: 327 | // - `google.rpc.OK`: the `leaf` data is the same as in the request. 328 | // - `google.rpc.ALREADY_EXISTS` or 'google.rpc.FAILED_PRECONDITION`: the 329 | // `leaf` is the conflicting one already in the log. 330 | LogLeaf leaf = 1; 331 | 332 | // The status of adding the leaf. 333 | // - `google.rpc.OK`: successfully added. 334 | // - `google.rpc.ALREADY_EXISTS`: the leaf is a duplicate of an already 335 | // existing one. Either `leaf_identity_hash` is the same in the `LOG` 336 | // mode, or `leaf_index` in the `PREORDERED_LOG`. 337 | // - `google.rpc.FAILED_PRECONDITION`: A conflicting entry is already 338 | // present in the log, e.g., same `leaf_index` but different `leaf_data`. 339 | google.rpc.Status status = 2; 340 | } 341 | 342 | // A leaf of the log's Merkle tree, corresponds to a single log entry. Each leaf 343 | // has a unique `leaf_index` in the scope of this tree. 344 | message LogLeaf { 345 | // Output only. The hash over `leaf_data`. 346 | bytes merkle_leaf_hash = 1; 347 | 348 | // Required. The arbitrary data associated with this log entry. Validity of 349 | // this field is governed by the call site (personality). 350 | bytes leaf_value = 2; 351 | // The arbitrary metadata, e.g., a timestamp. 352 | bytes extra_data = 3; 353 | 354 | // Output only in `LOG` mode. Required in `PREORDERED_LOG` mode. 355 | // The index of the leaf in the Merkle tree, i.e., the position of the 356 | // corresponding entry in the log. For normal logs this value will be 357 | // assigned by the LogSigner. 358 | int64 leaf_index = 4; 359 | 360 | // The hash over the identity of this leaf. If empty, assumed to be the same 361 | // as `merkle_leaf_hash`. It is a mechanism for the personality to provide a 362 | // hint to Trillian that two leaves should be considered "duplicates" even 363 | // though their `leaf_value`s differ. 364 | // 365 | // E.g., in a CT personality multiple `add-chain` calls for an identical 366 | // certificate would produce differing `leaf_data` bytes (due to the 367 | // presence of SCT elements), with just this information Trillian would be 368 | // unable to determine that. Within the context of the CT personality, these 369 | // entries are dupes, so it sets `leaf_identity_hash` to `H(cert)`, which 370 | // allows Trillian to detect the duplicates. 371 | // 372 | // Continuing the CT example, for a CT mirror personality (which must allow 373 | // dupes since the source log could contain them), the part of the 374 | // personality which fetches and submits the entries might set 375 | // `leaf_identity_hash` to `H(leaf_index||cert)`. 376 | // TODO(pavelkalinnikov): Consider instead using `H(cert)` and allowing 377 | // identity hash dupes in `PREORDERED_LOG` mode, for it can later be 378 | // upgraded to `LOG` which will need to correctly detect duplicates with 379 | // older entries when new ones get queued. 380 | bytes leaf_identity_hash = 5; 381 | 382 | // Output only. The time at which this leaf was passed to `QueueLeaves`. 383 | // This value will be determined and set by the LogServer. Equals zero if 384 | // the entry was submitted without queuing. 385 | google.protobuf.Timestamp queue_timestamp = 6; 386 | // Output only. The time at which this leaf was integrated into the tree. 387 | // This value will be determined and set by the LogSigner. 388 | google.protobuf.Timestamp integrate_timestamp = 7; 389 | } 390 | 391 | // A consistency or inclusion proof for a Merkle tree. Output only. 392 | message Proof { 393 | int64 leaf_index = 1; 394 | reserved 2; // Contained internal node details, no longer provided to clients. 395 | repeated bytes hashes = 3; 396 | } 397 | -------------------------------------------------------------------------------- /protofiles/trillian/trillian_log_sequencer_api.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package trillian; 18 | 19 | option go_package = "github.com/google/trillian"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "TrillianLogSequencerApiProto"; 22 | option java_package = "com.google.trillian.proto"; 23 | 24 | // The API supports sequencing in the Trillian Log Sequencer. 25 | service TrillianLogSequencer { 26 | } 27 | 28 | -------------------------------------------------------------------------------- /protofiles/trillian/trillian_map_api.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | option java_multiple_files = true; 18 | option java_package = "com.google.trillian.proto"; 19 | option java_outer_classname = "TrillianMapApiProto"; 20 | option go_package = "github.com/google/trillian"; 21 | 22 | package trillian; 23 | 24 | import "trillian.proto"; 25 | import "google/api/annotations.proto"; 26 | 27 | // MapLeaf represents the data behind Map leaves. 28 | message MapLeaf { 29 | // index is the location of this leaf. 30 | // All indexes for a given Map must contain a constant number of bits. 31 | // These are not numeric indices. Note that this is typically derived using a 32 | // hash and thus the length of all indices in the map will match the number 33 | // of bits in the hash function. Map entries do not have a well defined 34 | // ordering and it's not possible to sequentially iterate over them. 35 | bytes index = 1; 36 | // leaf_hash is the tree hash of leaf_value. This does not need to be set 37 | // on SetMapLeavesRequest; the server will fill it in. 38 | // For an empty leaf (len(leaf_value)==0), there may be two possible values 39 | // for this hash: 40 | // - If the leaf has never been set, it counts as an empty subtree and 41 | // a nil value is used. 42 | // - If the leaf has been explicitly set to a zero-length entry, it no 43 | // longer counts as empty and the value of hasher.HashLeaf(index, nil) 44 | // will be used. 45 | bytes leaf_hash = 2; 46 | // leaf_value is the data the tree commits to. 47 | bytes leaf_value = 3; 48 | // extra_data holds related contextual data, but is not covered by any hash. 49 | bytes extra_data = 4; 50 | } 51 | 52 | message MapLeafInclusion { 53 | MapLeaf leaf = 1; 54 | // inclusion holds the inclusion proof for this leaf in the map root. It 55 | // holds one entry for each level of the tree; combining each of these in 56 | // turn with the leaf's hash (according to the tree's hash strategy) 57 | // reproduces the root hash. A nil entry for a particular level indicates 58 | // that the node in question has an empty subtree beneath it (and so its 59 | // associated hash value is hasher.HashEmpty(index, height) rather than 60 | // hasher.HashChildren(l_hash, r_hash)). 61 | repeated bytes inclusion = 2; 62 | } 63 | 64 | message GetMapLeavesRequest { 65 | int64 map_id = 1; 66 | repeated bytes index = 2; 67 | reserved 3; // was 'revision' 68 | } 69 | 70 | // This message replaces the current implementation of GetMapLeavesRequest 71 | // with the difference that revision must be >=0. 72 | message GetMapLeavesByRevisionRequest { 73 | int64 map_id = 1; 74 | repeated bytes index = 2; 75 | // revision >= 0. 76 | int64 revision = 3; 77 | } 78 | 79 | message GetMapLeavesResponse { 80 | repeated MapLeafInclusion map_leaf_inclusion = 2; 81 | SignedMapRoot map_root = 3; 82 | } 83 | 84 | message SetMapLeavesRequest { 85 | int64 map_id = 1; 86 | // The leaves being set must have unique Index values within the request. 87 | repeated MapLeaf leaves = 2; 88 | reserved 3; // was MapperMetadata (removed, replaced by metadata). 89 | // Metadata that the Map should associate with the new Map root after 90 | // incorporating the leaf changes. The metadata will be reflected in the 91 | // Map Root returned in the map's SetLeaves response. 92 | // Map personalities should use metadata to persist any state needed later 93 | // to continue mapping from an external data source. 94 | reserved 4; 95 | bytes metadata = 5; 96 | } 97 | 98 | message SetMapLeavesResponse { 99 | SignedMapRoot map_root = 2; 100 | } 101 | 102 | message GetSignedMapRootRequest { 103 | int64 map_id = 1; 104 | } 105 | 106 | message GetSignedMapRootByRevisionRequest { 107 | int64 map_id = 1; 108 | int64 revision = 2; 109 | } 110 | 111 | message GetSignedMapRootResponse { 112 | SignedMapRoot map_root = 2; 113 | } 114 | 115 | message InitMapRequest { 116 | int64 map_id = 1; 117 | } 118 | 119 | message InitMapResponse { 120 | SignedMapRoot created = 1; 121 | } 122 | 123 | // TrillianMap defines a service which provides access to a Verifiable Map as 124 | // defined in the Verifiable Data Structures paper. 125 | service TrillianMap { 126 | // GetLeaves returns an inclusion proof for each index requested. 127 | // For indexes that do not exist, the inclusion proof will use nil for the empty leaf value. 128 | rpc GetLeaves(GetMapLeavesRequest) returns(GetMapLeavesResponse) {} 129 | rpc GetLeavesByRevision(GetMapLeavesByRevisionRequest) returns(GetMapLeavesResponse) {} 130 | // SetLeaves sets the values for the provided leaves, and returns the new map root if successful. 131 | // Note that if a SetLeaves request fails for a server-side reason (i.e. not an invalid request), 132 | // the API user is required to retry the request before performing a different SetLeaves request. 133 | rpc SetLeaves(SetMapLeavesRequest) returns(SetMapLeavesResponse) {} 134 | rpc GetSignedMapRoot(GetSignedMapRootRequest) returns(GetSignedMapRootResponse) { 135 | option (google.api.http) = { 136 | get: "/v1beta1/maps/{map_id}/roots:latest" 137 | }; 138 | } 139 | rpc GetSignedMapRootByRevision(GetSignedMapRootByRevisionRequest) returns(GetSignedMapRootResponse) { 140 | option (google.api.http) = { 141 | get: "/v1beta1/maps/{map_id}/roots/{revision}" 142 | }; 143 | } 144 | rpc InitMap(InitMapRequest) returns(InitMapResponse) { 145 | option (google.api.http) = { 146 | post: "/v1beta1/maps/{map_id}:init" 147 | }; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | // This is a placehoder file 2 | 3 | extern crate abci; 4 | 5 | use config; 6 | use vm_runtime; 7 | 8 | // Move VM 9 | 10 | #[allow(dead_code)] 11 | struct VM { 12 | runtime: vm_runtime::MoveVM, 13 | } 14 | 15 | impl Default for VM { 16 | fn default() -> VM { 17 | VM { 18 | runtime: vm_runtime::MoveVM::new(&config::config::VMConfig::default()), 19 | } 20 | } 21 | } 22 | 23 | // ABCI 24 | 25 | struct ABCIapp; 26 | impl abci::Application for ABCIapp {} 27 | 28 | // TODO: Abscissa 29 | // Examples: see `cargo-move` and `cargo-movemint` in the root directory 30 | 31 | #[allow(unused_variables)] 32 | fn main() { 33 | let movevm = VM::default(); // MoveVM with default config 34 | // TODO: verifer (`VMVerifier`) and executor (`VMExecutor`) 35 | 36 | abci::run_local(ABCIapp); 37 | } 38 | 39 | --------------------------------------------------------------------------------