diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index b69454a..bb88bff 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,113 @@ -# CosmWasm to Quint +

+ + + CoswmWasm to Quint + +

-This uses the crate `rustc_plugin` to generate quint code out of cosmwasm projects. To compile it, clone this repo and run: +*Semi-automated modelling and Model-Based Testing for [CosmWasm](https://cosmwasm.com/) contracts.* +1. Generate [Quint](https://github.com/informalsystems/quint) model stubs for a + contract, and only worry about specifying the important bits - the + entrypoints. +2. Generate tests to check that the model corresponds to the implementation by + attempting to reproduce traces. + +Quint provides powerful and friendly simulation and verification tools, but +first you need a model. This project **speeds up** the process of getting a model +for CosmWasm contracts. And, as a bonus, you can get as many integration tests +as you want, including tests to specific scenarios you deem important, through +**generated Model-Based tests**. + +This can be used to find bugs using the Quint tools and then getting them +reproduced in the real implementation with a generated test. For a better +understanding of how this whole process works, take a look at our [AwesomWasm +2024 Workshop +material](https://github.com/informalsystems/quint_awesomwasm24_workshop). + +## Is this ready to be used? + +Yes! + +Even though this tool is a prototype, it will make the best attempt to +generate as much as it can. It adds placeholders like `` to parts +it can't translate, which you then have to replace manually. But it is +definitely better than writing everything from scratch! + +See section [Known Limitations](#known-limitations) for problems to expect. + +## Examples + +If you want to see examples of generated code without running the tool yourself, +take a look at the [`tests/snapshots` +folder](https://github.com/informalsystems/cosmwasm-to-quint/tree/main/tests/snapshots). +We use [Oak Security's Capture the Flag +challenges](https://github.com/oak-security/cosmwasm-ctf) as tests, and these +snapshots contain both the model stubs and rust tests generated for each Capture +the Flag (CTF) challenge. + +## Setup and generation + +This project is implemented as a rust compiler plugin, in order to easily access +everything it needs from your CosmWasm contract. Because of that, we need a +couple extra steps in our setup, which in overview looks like this: +1. Install this tool +2. Use the nightly version of the rust compiler +3. Update your project's dependencies +4. Run the tool + +See detailed instructions below. + +### Installation + +To compile and install this project, clone this repo and run: ```bash # Install the cosmwasm-to-quint binaries cargo install --path . ``` -Running this tool for a CosmWasm contracts requires a simple `cargo` command, but you need to set some things up first. Make sure you are on the directory of your CosmWasm project and follow these steps: +### Setup + +Running this tool for a CosmWasm contracts requires a simple `cargo` command, +but you need to set some things up first. + +1. Go to the directory of your CosmWasm project -1. Setup `rustup` to use a `nightly` version compatible with compiler plugin libs +``` bash +cd /path/to/my-cosmwasm-project +``` + +2. Setup `rustup` to use a `nightly` version compatible with compiler plugin +libraries, and add the necessary components and target. **Important**: You also +need to update your project dependencies (`cargo update`) to match the new tool +chain, otherwise compilation will likely fail: ``` bash +# Install and use a nightly version rustup toolchain add nightly-2024-01-06 rustup override set nightly-2024-01-06 +# Add components and target rustup component add clippy rust-src rustc-dev llvm-tools-preview rustup target add wasm32-unknown-unknown +# Update dependencies on Cargo.lock to match the new tool chain +cargo update ``` -2. Because of this changes on the toolchain, you might need to remove any `Cargo.lock` files. Otherwise, you might hit a "unknown feature `proc_macro_span_shrink`" error. +### Generating the files -3. Since the translation is called by compiler callbacks, you need to make sure that the compiler is actually called. For that, remove any previous compilation results by calling `cargo clean` before executing this project's binary by calling `cargo cosmwasm-to-quint` +Since the translation is called by compiler callbacks, you need to make sure +that the compiler is actually called. For that, remove any previous compilation +results by calling `cargo clean` before executing this project's binary by +calling `cargo cosmwasm-to-quint` ``` bash cargo clean && cargo cosmwasm-to-quint ``` -4. In order to run the generated tests, you'll need to add some dependencies: +### Running the generated tests + +1. In order to run the generated tests, you'll need to add some dependencies: ```bash cargo add cw-multi-test@0.16.2 --dev cargo add itf@0.2.4 --dev @@ -36,4 +116,63 @@ cargo add num-bigint@0.4.4 --dev cargo add num-traits@0.2.17 --dev ``` -5. TODO: Add instructions on how to produce traces for the test +2. The tests also require a trace. By default, it will look for the + `quint/test.itf.json` file, but you can change this path in the test file. + The trace is some execution from the Quint model, which the test will attempt + to reproduce in your contract. You should always use the `--mbt` flag to tell + Quint to include test-relevant information to the trace (this option is + available from Quint `v0.20.0`). + +There are a number of ways to obtain a trace, but the simplest one is: + +``` bash +quint run quint/my_model.qnt --mbt --out-itf=quint/test.itf.json +``` + +Alternatively, if you have an invariant that is being violated in the model and +want to reproduce a counterexample of that invariant in the contract, simply +provide the invariant to the command: + +``` bash +quint run quint/my_model.qnt --mbt --out-itf=quint/test.itf.json --invariant=my_invariant +``` + +You can also use this to obtain interesting traces. Say you want a test where +Alice spends all of her ATOMs. You can write an invariant like +`balances.get("Alice").get("ATOM") > 0` and then use it to obtain a trace +violating that invariant. + +3. Run the tests: + +``` bash +cargo test +``` + +## Known limitations +- **Imports from different crates**: this is something we want to support, but + it is not trivial. Right now, if your contract crate imports core data + structures or other items that are necessary for the generation, you'll have + unresolved names and placeholders to fill for each of them. Of course, this + doesn't apply to common imports from `cosmwasm_std` which are already dealt + with. +- **Multiple contract interactions**: this is probably the next important step + for this project, but we are not there yet. If you need to model and test + interactions between multiple contracts, you will need to do a lot of the + wiring manually. Fortunately, we believe it is possible to automate this, so + let us know if this would be useful for your project! + +## Troubleshooting +1. I see an "unknown feature `proc_macro_span_shrink`" error + +You probably forgot to run `cargo update` after switching the tool chain + +2. Running `cargo cosmwasm-to-quint` exits immediately and doesn't + produce/update any files + +You probably forgot to run `cargo clean` before running the command + +3. I'm getting duplicated definitions for a bunch of things + +Make sure you have **not** added a generated test file to your contract's crate +somehow. If you do that, this tool will read the test file as it was part of +your contract and, therefore, generate duplicated items. diff --git a/images/cosmwasm-to-quint-dark.png b/images/cosmwasm-to-quint-dark.png new file mode 100644 index 0000000..490c5f7 Binary files /dev/null and b/images/cosmwasm-to-quint-dark.png differ diff --git a/images/cosmwasm-to-quint-light.png b/images/cosmwasm-to-quint-light.png new file mode 100644 index 0000000..2a2e711 Binary files /dev/null and b/images/cosmwasm-to-quint-light.png differ