From f4606ea6982e6456b76bd808dcaa943806268914 Mon Sep 17 00:00:00 2001 From: howardwu Date: Sun, 30 May 2021 21:55:18 -0700 Subject: [PATCH] Refresh integration test with local ledger impl --- .snarkos-integration/Cargo.toml | 52 +- .snarkos-integration/LICENSE.md | 596 +++++++++++++++++ .snarkos-integration/src/dpc.rs | 78 +++ .snarkos-integration/src/ledger.rs | 630 ++++++++++++++++++ .snarkos-integration/src/lib.rs | 87 +++ .snarkos-integration/src/memdb.rs | 86 +++ .snarkos-integration/src/storage.rs | 124 ++++ .../tests/{base_dpc.rs => dpc_testnet1.rs} | 54 +- Cargo.lock | 517 +++----------- 9 files changed, 1725 insertions(+), 499 deletions(-) create mode 100644 .snarkos-integration/LICENSE.md create mode 100644 .snarkos-integration/src/dpc.rs create mode 100644 .snarkos-integration/src/ledger.rs create mode 100644 .snarkos-integration/src/lib.rs create mode 100644 .snarkos-integration/src/memdb.rs create mode 100644 .snarkos-integration/src/storage.rs rename .snarkos-integration/tests/{base_dpc.rs => dpc_testnet1.rs} (94%) diff --git a/.snarkos-integration/Cargo.toml b/.snarkos-integration/Cargo.toml index 773e45e323..07d5601eee 100644 --- a/.snarkos-integration/Cargo.toml +++ b/.snarkos-integration/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "snarkvm-snarkos-integration" -version = "0.3.1" +name = "snarkvm-integration" +version = "0.4.0" authors = [ "The Aleo Team " ] -description = "A test suite for functionalities requiring snarkOS integration" +description = "Integration testing for DPC" homepage = "https://aleo.org" repository = "https://github.com/AleoHQ/snarkVM" keywords = [ @@ -18,43 +18,32 @@ license = "GPL-3.0" edition = "2018" [dependencies.snarkvm-algorithms] -version = "0.3.1" -default-features = false +path = "../algorithms" [dependencies.snarkvm-curves] -version = "0.3.1" -default-features = false +path = "../curves" [dependencies.snarkvm-dpc] -version = "0.3.1" -default-features = false +path = "../dpc" [dependencies.snarkvm-fields] -version = "0.3.1" -default-features = false +path = "../fields" [dependencies.snarkvm-gadgets] -version = "0.3.1" -default-features = false - -[dependencies.snarkvm-objects] -version = "0.3.1" -default-features = false +path = "../gadgets" [dependencies.snarkvm-parameters] -version = "0.3.1" -default-features = false +path = "../parameters" [dependencies.snarkvm-profiler] -version = "0.3.1" +path = "../profiler" default-features = false [dependencies.snarkvm-r1cs] -version = "0.3.1" -default-features = false +path = "../r1cs" [dependencies.snarkvm-utilities] -version = "0.3.1" +path = "../utilities" default-features = false [dependencies.anyhow] @@ -66,6 +55,9 @@ version = "0.1" [dependencies.bech32] version = "0.8" +[dependencies.bincode] +version = "1.3.1" + [dependencies.blake2] version = "0.9" @@ -78,20 +70,12 @@ version = "0.4.3" [dependencies.itertools] version = "0.10.0" +[dependencies.parking_lot] +version = "0.11.1" + [dependencies.rand] version = "0.8" -[dependencies.snarkos-storage] -git = "https://github.com/AleoHQ/snarkOS" -rev = "e72d3d9d03d1a053ae148608e3f5b3ae857a4edf" # version 1.3.6 of the package -default-features = false -features = ["mem_storage"] - -[dependencies.snarkos-testing] -git = "https://github.com/AleoHQ/snarkOS" -rev = "e72d3d9d03d1a053ae148608e3f5b3ae857a4edf" # version 1.3.6 of the package -default-features = false - [dependencies.thiserror] version = "1.0" diff --git a/.snarkos-integration/LICENSE.md b/.snarkos-integration/LICENSE.md new file mode 100644 index 0000000000..b95c626e2a --- /dev/null +++ b/.snarkos-integration/LICENSE.md @@ -0,0 +1,596 @@ +GNU General Public License +========================== + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <> + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +## Preamble + +The GNU General Public License is a free, copyleft license for software and other +kinds of works. + +The licenses for most software and other practical works are designed to take away +your freedom to share and change the works. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change all versions of a +program--to make sure it remains free software for all its users. We, the Free +Software Foundation, use the GNU General Public License for most of our software; it +applies also to any other work released this way by its authors. You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General +Public Licenses are designed to make sure that you have the freedom to distribute +copies of free software (and charge for them if you wish), that you receive source +code or can get it if you want it, that you can change the software or use pieces of +it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or +asking you to surrender the rights. Therefore, you have certain responsibilities if +you distribute copies of the software, or if you modify it: responsibilities to +respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, +you must pass on to the recipients the same freedoms that you received. You must make +sure that they, too, receive or can get the source code. And you must show them these +terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: **(1)** assert +copyright on the software, and **(2)** offer you this License giving you legal permission +to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is +no warranty for this free software. For both users' and authors' sake, the GPL +requires that modified versions be marked as changed, so that their problems will not +be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of +the software inside them, although the manufacturer can do so. This is fundamentally +incompatible with the aim of protecting users' freedom to change the software. The +systematic pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we have designed +this version of the GPL to prohibit the practice for those products. If such problems +arise substantially in other domains, we stand ready to extend this provision to +those domains in future versions of the GPL, as needed to protect the freedom of +users. + +Finally, every program is threatened constantly by software patents. States should +not allow patents to restrict development and use of software on general-purpose +computers, but in those that do, we wish to avoid the special danger that patents +applied to a free program could make it effectively proprietary. To prevent this, the +GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +## TERMS AND CONDITIONS + +### 0. Definitions + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this +License. Each licensee is addressed as “you”. “Licensees” and +“recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in +a fashion requiring copyright permission, other than the making of an exact copy. The +resulting work is called a “modified version” of the earlier work or a +work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on +the Program. + +To “propagate” a work means to do anything with it that, without +permission, would make you directly or secondarily liable for infringement under +applicable copyright law, except executing it on a computer or modifying a private +copy. Propagation includes copying, distribution (with or without modification), +making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through a computer +network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the +extent that it includes a convenient and prominently visible feature that **(1)** +displays an appropriate copyright notice, and **(2)** tells the user that there is no +warranty for the work (except to the extent that warranties are provided), that +licensees may convey the work under this License, and how to view a copy of this +License. If the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +### 1. Source Code + +The “source code” for a work means the preferred form of the work for +making modifications to it. “Object code” means any non-source form of a +work. + +A “Standard Interface” means an interface that either is an official +standard defined by a recognized standards body, or, in the case of interfaces +specified for a particular programming language, one that is widely used among +developers working in that language. + +The “System Libraries” of an executable work include anything, other than +the work as a whole, that **(a)** is included in the normal form of packaging a Major +Component, but which is not part of that Major Component, and **(b)** serves only to +enable use of the work with that Major Component, or to implement a Standard +Interface for which an implementation is available to the public in source code form. +A “Major Component”, in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system (if any) on which +the executable work runs, or a compiler used to produce the work, or an object code +interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the +source code needed to generate, install, and (for an executable work) run the object +code and to modify the work, including scripts to control those activities. However, +it does not include the work's System Libraries, or general-purpose tools or +generally available free programs which are used unmodified in performing those +activities but which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for the work, and +the source code for shared libraries and dynamically linked subprograms that the work +is specifically designed to require, such as by intimate data communication or +control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate +automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +### 2. Basic Permissions + +All rights granted under this License are granted for the term of copyright on the +Program, and are irrevocable provided the stated conditions are met. This License +explicitly affirms your unlimited permission to run the unmodified Program. The +output from running a covered work is covered by this License only if the output, +given its content, constitutes a covered work. This License acknowledges your rights +of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without +conditions so long as your license otherwise remains in force. You may convey covered +works to others for the sole purpose of having them make modifications exclusively +for you, or provide you with facilities for running those works, provided that you +comply with the terms of this License in conveying all material for which you do not +control copyright. Those thus making or running the covered works for you must do so +exclusively on your behalf, under your direction and control, on terms that prohibit +them from making any copies of your copyrighted material outside their relationship +with you. + +Conveying under any other circumstances is permitted solely under the conditions +stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +### 3. Protecting Users' Legal Rights From Anti-Circumvention Law + +No covered work shall be deemed part of an effective technological measure under any +applicable law fulfilling obligations under article 11 of the WIPO copyright treaty +adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention +of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of +technological measures to the extent such circumvention is effected by exercising +rights under this License with respect to the covered work, and you disclaim any +intention to limit operation or modification of the work as a means of enforcing, +against the work's users, your or third parties' legal rights to forbid circumvention +of technological measures. + +### 4. Conveying Verbatim Copies + +You may convey verbatim copies of the Program's source code as you receive it, in any +medium, provided that you conspicuously and appropriately publish on each copy an +appropriate copyright notice; keep intact all notices stating that this License and +any non-permissive terms added in accord with section 7 apply to the code; keep +intact all notices of the absence of any warranty; and give all recipients a copy of +this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer +support or warranty protection for a fee. + +### 5. Conveying Modified Source Versions + +You may convey a work based on the Program, or the modifications to produce it from +the Program, in the form of source code under the terms of section 4, provided that +you also meet all of these conditions: + +* **a)** The work must carry prominent notices stating that you modified it, and giving a +relevant date. +* **b)** The work must carry prominent notices stating that it is released under this +License and any conditions added under section 7. This requirement modifies the +requirement in section 4 to “keep intact all notices”. +* **c)** You must license the entire work, as a whole, under this License to anyone who +comes into possession of a copy. This License will therefore apply, along with any +applicable section 7 additional terms, to the whole of the work, and all its parts, +regardless of how they are packaged. This License gives no permission to license the +work in any other way, but it does not invalidate such permission if you have +separately received it. +* **d)** If the work has interactive user interfaces, each must display Appropriate Legal +Notices; however, if the Program has interactive interfaces that do not display +Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are +not by their nature extensions of the covered work, and which are not combined with +it such as to form a larger program, in or on a volume of a storage or distribution +medium, is called an “aggregate” if the compilation and its resulting +copyright are not used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work in an aggregate +does not cause this License to apply to the other parts of the aggregate. + +### 6. Conveying Non-Source Forms + +You may convey a covered work in object code form under the terms of sections 4 and +5, provided that you also convey the machine-readable Corresponding Source under the +terms of this License, in one of these ways: + +* **a)** Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by the Corresponding Source fixed on a +durable physical medium customarily used for software interchange. +* **b)** Convey the object code in, or embodied in, a physical product (including a +physical distribution medium), accompanied by a written offer, valid for at least +three years and valid for as long as you offer spare parts or customer support for +that product model, to give anyone who possesses the object code either **(1)** a copy of +the Corresponding Source for all the software in the product that is covered by this +License, on a durable physical medium customarily used for software interchange, for +a price no more than your reasonable cost of physically performing this conveying of +source, or **(2)** access to copy the Corresponding Source from a network server at no +charge. +* **c)** Convey individual copies of the object code with a copy of the written offer to +provide the Corresponding Source. This alternative is allowed only occasionally and +noncommercially, and only if you received the object code with such an offer, in +accord with subsection 6b. +* **d)** Convey the object code by offering access from a designated place (gratis or for +a charge), and offer equivalent access to the Corresponding Source in the same way +through the same place at no further charge. You need not require recipients to copy +the Corresponding Source along with the object code. If the place to copy the object +code is a network server, the Corresponding Source may be on a different server +(operated by you or a third party) that supports equivalent copying facilities, +provided you maintain clear directions next to the object code saying where to find +the Corresponding Source. Regardless of what server hosts the Corresponding Source, +you remain obligated to ensure that it is available for as long as needed to satisfy +these requirements. +* **e)** Convey the object code using peer-to-peer transmission, provided you inform +other peers where the object code and Corresponding Source of the work are being +offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the +Corresponding Source as a System Library, need not be included in conveying the +object code work. + +A “User Product” is either **(1)** a “consumer product”, which +means any tangible personal property which is normally used for personal, family, or +household purposes, or **(2)** anything designed or sold for incorporation into a +dwelling. In determining whether a product is a consumer product, doubtful cases +shall be resolved in favor of coverage. For a particular product received by a +particular user, “normally used” refers to a typical or common use of +that class of product, regardless of the status of the particular user or of the way +in which the particular user actually uses, or expects or is expected to use, the +product. A product is a consumer product regardless of whether the product has +substantial commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, +procedures, authorization keys, or other information required to install and execute +modified versions of a covered work in that User Product from a modified version of +its Corresponding Source. The information must suffice to ensure that the continued +functioning of the modified object code is in no case prevented or interfered with +solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for +use in, a User Product, and the conveying occurs as part of a transaction in which +the right of possession and use of the User Product is transferred to the recipient +in perpetuity or for a fixed term (regardless of how the transaction is +characterized), the Corresponding Source conveyed under this section must be +accompanied by the Installation Information. But this requirement does not apply if +neither you nor any third party retains the ability to install modified object code +on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to +continue to provide support service, warranty, or updates for a work that has been +modified or installed by the recipient, or for the User Product in which it has been +modified or installed. Access to a network may be denied when the modification itself +materially and adversely affects the operation of the network or violates the rules +and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with +this section must be in a format that is publicly documented (and with an +implementation available to the public in source code form), and must require no +special password or key for unpacking, reading or copying. + +### 7. Additional Terms + +“Additional permissions” are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. Additional +permissions that are applicable to the entire Program shall be treated as though they +were included in this License, to the extent that they are valid under applicable +law. If additional permissions apply only to part of the Program, that part may be +used separately under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any +additional permissions from that copy, or from any part of it. (Additional +permissions may be written to require their own removal in certain cases when you +modify the work.) You may place additional permissions on material, added by you to a +covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a +covered work, you may (if authorized by the copyright holders of that material) +supplement the terms of this License with terms: + +* **a)** Disclaiming warranty or limiting liability differently from the terms of +sections 15 and 16 of this License; or +* **b)** Requiring preservation of specified reasonable legal notices or author +attributions in that material or in the Appropriate Legal Notices displayed by works +containing it; or +* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that +modified versions of such material be marked in reasonable ways as different from the +original version; or +* **d)** Limiting the use for publicity purposes of names of licensors or authors of the +material; or +* **e)** Declining to grant rights under trademark law for use of some trade names, +trademarks, or service marks; or +* **f)** Requiring indemnification of licensors and authors of that material by anyone +who conveys the material (or modified versions of it) with contractual assumptions of +liability to the recipient, for any liability that these contractual assumptions +directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further +restrictions” within the meaning of section 10. If the Program as you received +it, or any part of it, contains a notice stating that it is governed by this License +along with a term that is a further restriction, you may remove that term. If a +license document contains a further restriction but permits relicensing or conveying +under this License, you may add to a covered work material governed by the terms of +that license document, provided that the further restriction does not survive such +relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in +the relevant source files, a statement of the additional terms that apply to those +files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a +separately written license, or stated as exceptions; the above requirements apply +either way. + +### 8. Termination + +You may not propagate or modify a covered work except as expressly provided under +this License. Any attempt otherwise to propagate or modify it is void, and will +automatically terminate your rights under this License (including any patent licenses +granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a +particular copyright holder is reinstated **(a)** provisionally, unless and until the +copyright holder explicitly and finally terminates your license, and **(b)** permanently, +if the copyright holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently +if the copyright holder notifies you of the violation by some reasonable means, this +is the first time you have received notice of violation of this License (for any +work) from that copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of +parties who have received copies or rights from you under this License. If your +rights have been terminated and not permanently reinstated, you do not qualify to +receive new licenses for the same material under section 10. + +### 9. Acceptance Not Required for Having Copies + +You are not required to accept this License in order to receive or run a copy of the +Program. Ancillary propagation of a covered work occurring solely as a consequence of +using peer-to-peer transmission to receive a copy likewise does not require +acceptance. However, nothing other than this License grants you permission to +propagate or modify any covered work. These actions infringe copyright if you do not +accept this License. Therefore, by modifying or propagating a covered work, you +indicate your acceptance of this License to do so. + +### 10. Automatic Licensing of Downstream Recipients + +Each time you convey a covered work, the recipient automatically receives a license +from the original licensors, to run, modify and propagate that work, subject to this +License. You are not responsible for enforcing compliance by third parties with this +License. + +An “entity transaction” is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an organization, or +merging organizations. If propagation of a covered work results from an entity +transaction, each party to that transaction who receives a copy of the work also +receives whatever licenses to the work the party's predecessor in interest had or +could give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if the predecessor +has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or +affirmed under this License. For example, you may not impose a license fee, royalty, +or other charge for exercise of rights granted under this License, and you may not +initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging +that any patent claim is infringed by making, using, selling, offering for sale, or +importing the Program or any portion of it. + +### 11. Patents + +A “contributor” is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The work thus +licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or +controlled by the contributor, whether already acquired or hereafter acquired, that +would be infringed by some manner, permitted by this License, of making, using, or +selling its contributor version, but do not include claims that would be infringed +only as a consequence of further modification of the contributor version. For +purposes of this definition, “control” includes the right to grant patent +sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license +under the contributor's essential patent claims, to make, use, sell, offer for sale, +import and otherwise run, modify and propagate the contents of its contributor +version. + +In the following three paragraphs, a “patent license” is any express +agreement or commitment, however denominated, not to enforce a patent (such as an +express permission to practice a patent or covenant not to sue for patent +infringement). To “grant” such a patent license to a party means to make +such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the +Corresponding Source of the work is not available for anyone to copy, free of charge +and under the terms of this License, through a publicly available network server or +other readily accessible means, then you must either **(1)** cause the Corresponding +Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the +patent license for this particular work, or **(3)** arrange, in a manner consistent with +the requirements of this License, to extend the patent license to downstream +recipients. “Knowingly relying” means you have actual knowledge that, but +for the patent license, your conveying the covered work in a country, or your +recipient's use of the covered work in a country, would infringe one or more +identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you +convey, or propagate by procuring conveyance of, a covered work, and grant a patent +license to some of the parties receiving the covered work authorizing them to use, +propagate, modify or convey a specific copy of the covered work, then the patent +license you grant is automatically extended to all recipients of the covered work and +works based on it. + +A patent license is “discriminatory” if it does not include within the +scope of its coverage, prohibits the exercise of, or is conditioned on the +non-exercise of one or more of the rights that are specifically granted under this +License. You may not convey a covered work if you are a party to an arrangement with +a third party that is in the business of distributing software, under which you make +payment to the third party based on the extent of your activity of conveying the +work, and under which the third party grants, to any of the parties who would receive +the covered work from you, a discriminatory patent license **(a)** in connection with +copies of the covered work conveyed by you (or copies made from those copies), or **(b)** +primarily for and in connection with specific products or compilations that contain +the covered work, unless you entered into that arrangement, or that patent license +was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied +license or other defenses to infringement that may otherwise be available to you +under applicable patent law. + +### 12. No Surrender of Others' Freedom + +If conditions are imposed on you (whether by court order, agreement or otherwise) +that contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot convey a covered work so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not convey it at all. For example, if you +agree to terms that obligate you to collect a royalty for further conveying from +those to whom you convey the Program, the only way you could satisfy both those terms +and this License would be to refrain entirely from conveying the Program. + +### 13. Use with the GNU Affero General Public License + +Notwithstanding any other provision of this License, you have permission to link or +combine any covered work with a work licensed under version 3 of the GNU Affero +General Public License into a single combined work, and to convey the resulting work. +The terms of this License will continue to apply to the part which is the covered +work, but the special requirements of the GNU Affero General Public License, section +13, concerning interaction through a network will apply to the combination as such. + +### 14. Revised Versions of this License + +The Free Software Foundation may publish revised and/or new versions of the GNU +General Public License from time to time. Such new versions will be similar in spirit +to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that +a certain numbered version of the GNU General Public License “or any later +version” applies to it, you have the option of following the terms and +conditions either of that numbered version or of any later version published by the +Free Software Foundation. If the Program does not specify a version number of the GNU +General Public License, you may choose any version ever published by the Free +Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU +General Public License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no +additional obligations are imposed on any author or copyright holder as a result of +your choosing to follow a later version. + +### 15. Disclaimer of Warranty + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE +QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +### 16. Limitation of Liability + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY +COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS +PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, +INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE +OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE +WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +### 17. Interpretation of Sections 15 and 16 + +If the disclaimer of warranty and limitation of liability provided above cannot be +given local legal effect according to their terms, reviewing courts shall apply local +law that most closely approximates an absolute waiver of all civil liability in +connection with the Program, unless a warranty or assumption of liability accompanies +a copy of the Program in return for a fee. + +_END OF TERMS AND CONDITIONS_ + +## How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to +the public, the best way to achieve this is to make it free software which everyone +can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them +to the start of each source file to most effectively state the exclusion of warranty; +and each file should have at least the “copyright” line and a pointer to +where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this +when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type 'show c' for details. + +The hypothetical commands `show w` and `show c` should show the appropriate parts of +the General Public License. Of course, your program's commands might be different; +for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to +sign a “copyright disclaimer” for the program, if necessary. For more +information on this, and how to apply and follow the GNU GPL, see +<>. + +The GNU General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may consider it +more useful to permit linking proprietary applications with the library. If this is +what you want to do, use the GNU Lesser General Public License instead of this +License. But first, please read +<>. diff --git a/.snarkos-integration/src/dpc.rs b/.snarkos-integration/src/dpc.rs new file mode 100644 index 0000000000..40744a4f45 --- /dev/null +++ b/.snarkos-integration/src/dpc.rs @@ -0,0 +1,78 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the snarkVM library. + +// The snarkVM library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The snarkVM library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the snarkVM library. If not, see . + +use crate::Ledger; +use snarkvm_algorithms::{MerkleParameters, CRH}; +use snarkvm_dpc::{ + testnet1::{instantiated::*, parameters::PublicParameters}, + Account, + AccountScheme, + DPCScheme, + Storage, +}; +use snarkvm_parameters::{LedgerMerkleTreeParameters, Parameter}; +use snarkvm_utilities::bytes::FromBytes; + +use rand::Rng; +use std::sync::Arc; + +pub type MerkleTreeLedger = Ledger; + +pub fn setup_or_load_parameters( + verify_only: bool, + rng: &mut R, +) -> ( + Arc, + >>::NetworkParameters, +) { + // TODO (howardwu): Resolve this inconsistency on import structure with a new model once MerkleParameters are refactored. + let crh_parameters = + ::Parameters::read(&LedgerMerkleTreeParameters::load_bytes().unwrap()[..]) + .expect("read bytes as hash for MerkleParameters in ledger"); + let merkle_tree_hash_parameters = ::H::from(crh_parameters); + let ledger_merkle_tree_parameters = Arc::new(From::from(merkle_tree_hash_parameters)); + + let parameters = match >>::NetworkParameters::load(verify_only) { + Ok(parameters) => parameters, + Err(err) => { + println!("error - {}, re-running parameter Setup", err); + >>::setup(&ledger_merkle_tree_parameters, rng) + .expect("DPC setup failed") + } + }; + + (ledger_merkle_tree_parameters, parameters) +} + +pub fn load_verifying_parameters() -> PublicParameters { + PublicParameters::::load_vk_direct().unwrap() +} + +pub fn generate_test_accounts( + parameters: &PublicParameters, + rng: &mut R, +) -> [Account; 3] { + let signature_parameters = ¶meters.system_parameters.account_signature; + let commitment_parameters = ¶meters.system_parameters.account_commitment; + let encryption_parameters = ¶meters.system_parameters.account_encryption; + + let genesis_account = + Account::new(signature_parameters, commitment_parameters, encryption_parameters, rng).unwrap(); + let account_1 = Account::new(signature_parameters, commitment_parameters, encryption_parameters, rng).unwrap(); + let account_2 = Account::new(signature_parameters, commitment_parameters, encryption_parameters, rng).unwrap(); + + [genesis_account, account_1, account_2] +} diff --git a/.snarkos-integration/src/ledger.rs b/.snarkos-integration/src/ledger.rs new file mode 100644 index 0000000000..0bd92556bb --- /dev/null +++ b/.snarkos-integration/src/ledger.rs @@ -0,0 +1,630 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the snarkVM library. + +// The snarkVM library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The snarkVM library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the snarkVM library. If not, see . + +use crate::*; +use snarkvm_algorithms::{merkle_tree::*, traits::LoadableMerkleParameters}; +use snarkvm_dpc::prelude::*; +use snarkvm_utilities::{ + bytes::{FromBytes, ToBytes}, + has_duplicates, + to_bytes, +}; + +use parking_lot::RwLock; +use std::{ + collections::HashSet, + fs, + marker::PhantomData, + path::Path, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, + }, +}; + +pub type BlockHeight = u32; + +pub struct Ledger { + pub current_block_height: AtomicU32, + pub ledger_parameters: Arc

, + pub cm_merkle_tree: RwLock>, + pub storage: S, + pub _transaction: PhantomData, +} + +impl Ledger { + /// Returns true if there are no blocks in the ledger. + pub fn is_empty(&self) -> bool { + self.get_latest_block().is_err() + } + + /// Get the latest block in the chain. + pub fn get_latest_block(&self) -> Result, StorageError> { + self.get_block_from_block_number(self.get_current_block_height()) + } + + /// Get a block given the block hash. + pub fn get_block(&self, block_hash: &BlockHeaderHash) -> Result, StorageError> { + Ok(Block { + header: self.get_block_header(block_hash)?, + transactions: self.get_block_transactions(block_hash)?, + }) + } + + /// Get a block given the block number. + pub fn get_block_from_block_number(&self, block_number: u32) -> Result, StorageError> { + if block_number > self.get_current_block_height() { + return Err(StorageError::BlockError(BlockError::InvalidBlockNumber(block_number))); + } + + let block_hash = self.get_block_hash(block_number)?; + + self.get_block(&block_hash) + } + + /// Get the block hash given a block number. + pub fn get_block_hash(&self, block_number: u32) -> Result { + match self.storage.get(COL_BLOCK_LOCATOR, &block_number.to_le_bytes())? { + Some(block_header_hash) => Ok(BlockHeaderHash::new(block_header_hash)), + None => Err(StorageError::MissingBlockHash(block_number)), + } + } + + /// Get the list of transaction ids given a block hash. + pub fn get_block_transactions(&self, block_hash: &BlockHeaderHash) -> Result, StorageError> { + match self.storage.get(COL_BLOCK_TRANSACTIONS, &block_hash.0)? { + Some(encoded_block_transactions) => Ok(Transactions::read(&encoded_block_transactions[..])?), + None => Err(StorageError::MissingBlockTransactions(block_hash.to_string())), + } + } + + /// Find the potential child block hashes given a parent block header. + pub fn get_child_block_hashes( + &self, + parent_header: &BlockHeaderHash, + ) -> Result, StorageError> { + match self.storage.get(COL_CHILD_HASHES, &parent_header.0)? { + Some(encoded_child_block_hashes) => Ok(bincode::deserialize(&encoded_child_block_hashes[..])?), + None => Ok(vec![]), + } + } + + /// Get the latest block height of the chain. + pub fn get_current_block_height(&self) -> BlockHeight { + self.current_block_height.load(Ordering::SeqCst) + } + + /// Get the block number given a block hash. + pub fn get_block_number(&self, block_hash: &BlockHeaderHash) -> Result { + match self.storage.get(COL_BLOCK_LOCATOR, &block_hash.0)? { + Some(block_num_bytes) => Ok(bytes_to_u32(&block_num_bytes)), + None => Err(StorageError::MissingBlockNumber(block_hash.to_string())), + } + } + + /// Returns true if the block for the given block header hash exists. + pub fn block_hash_exists(&self, block_hash: &BlockHeaderHash) -> bool { + if self.is_empty() { + return false; + } + + self.get_block_header(block_hash).is_ok() + } + + /// Get a block header given the block hash. + pub fn get_block_header(&self, block_hash: &BlockHeaderHash) -> Result { + match self.storage.get(COL_BLOCK_HEADER, &block_hash.0)? { + Some(block_header_bytes) => Ok(BlockHeader::read(&block_header_bytes[..])?), + None => Err(StorageError::MissingBlockHeader(block_hash.to_string())), + } + } + + /// Get the current commitment index + pub fn current_cm_index(&self) -> Result { + match self.storage.get(COL_META, KEY_CURR_CM_INDEX.as_bytes())? { + Some(cm_index_bytes) => Ok(bytes_to_u32(&cm_index_bytes) as usize), + None => Ok(0), + } + } + + /// Get the current serial number index + pub fn current_sn_index(&self) -> Result { + match self.storage.get(COL_META, KEY_CURR_SN_INDEX.as_bytes())? { + Some(sn_index_bytes) => Ok(bytes_to_u32(&sn_index_bytes) as usize), + None => Ok(0), + } + } + + /// Get the current memo index + pub fn current_memo_index(&self) -> Result { + match self.storage.get(COL_META, KEY_CURR_MEMO_INDEX.as_bytes())? { + Some(memo_index_bytes) => Ok(bytes_to_u32(&memo_index_bytes) as usize), + None => Ok(0), + } + } + + /// Get the current ledger digest + pub fn current_digest(&self) -> Result, StorageError> { + match self.storage.get(COL_META, KEY_CURR_DIGEST.as_bytes())? { + Some(current_digest) => Ok(current_digest), + None => Ok(to_bytes![self.cm_merkle_tree.read().root()].unwrap()), + } + } + + /// Get the set of past ledger digests + pub fn past_digests(&self) -> Result>, StorageError> { + let keys = self.storage.get_keys(COL_DIGEST)?; + let digests = keys.into_iter().collect(); + + Ok(digests) + } + + /// Get serial number index. + pub fn get_sn_index(&self, sn_bytes: &[u8]) -> Result, StorageError> { + match self.storage.get(COL_SERIAL_NUMBER, sn_bytes)? { + Some(sn_index_bytes) => { + let mut sn_index = [0u8; 4]; + sn_index.copy_from_slice(&sn_index_bytes[0..4]); + + Ok(Some(u32::from_le_bytes(sn_index) as usize)) + } + None => Ok(None), + } + } + + /// Get commitment index + pub fn get_cm_index(&self, cm_bytes: &[u8]) -> Result, StorageError> { + match self.storage.get(COL_COMMITMENT, cm_bytes)? { + Some(cm_index_bytes) => { + let mut cm_index = [0u8; 4]; + cm_index.copy_from_slice(&cm_index_bytes[0..4]); + + Ok(Some(u32::from_le_bytes(cm_index) as usize)) + } + None => Ok(None), + } + } + + /// Get memo index + pub fn get_memo_index(&self, memo_bytes: &[u8]) -> Result, StorageError> { + match self.storage.get(COL_MEMO, memo_bytes)? { + Some(memo_index_bytes) => { + let mut memo_index = [0u8; 4]; + memo_index.copy_from_slice(&memo_index_bytes[0..4]); + + Ok(Some(u32::from_le_bytes(memo_index) as usize)) + } + None => Ok(None), + } + } + + /// Build a new commitment merkle tree from the stored commitments + pub fn rebuild_merkle_tree(&self, additional_cms: Vec<(T::Commitment, usize)>) -> Result<(), StorageError> { + let mut new_cm_and_indices = additional_cms; + + let mut old_cm_and_indices = vec![]; + for (commitment_key, index_value) in self.storage.get_col(COL_COMMITMENT)? { + let commitment: T::Commitment = FromBytes::read(&commitment_key[..])?; + let index = bytes_to_u32(&index_value) as usize; + + old_cm_and_indices.push((commitment, index)); + } + + old_cm_and_indices.sort_by(|&(_, i), &(_, j)| i.cmp(&j)); + new_cm_and_indices.sort_by(|&(_, i), &(_, j)| i.cmp(&j)); + + let old_commitments = old_cm_and_indices.into_iter().map(|(cm, _)| cm); + let new_commitments: Vec<_> = new_cm_and_indices.into_iter().map(|(cm, _)| cm).collect(); + + let new_tree = { self.cm_merkle_tree.read().rebuild(old_commitments, &new_commitments)? }; + *self.cm_merkle_tree.write() = new_tree; + + Ok(()) + } +} + +impl LedgerScheme for Ledger { + type Block = Block; + type Commitment = T::Commitment; + type MerkleParameters = P; + type MerklePath = MerklePath; + type MerkleTreeDigest = MerkleTreeDigest; + type SerialNumber = T::SerialNumber; + type Transaction = T; + + /// Instantiates a new ledger with a genesis block. + fn new( + path: Option<&Path>, + parameters: Arc, + genesis_block: Self::Block, + ) -> anyhow::Result { + let storage = if let Some(path) = path { + fs::create_dir_all(&path).map_err(|err| LedgerError::Message(err.to_string()))?; + + S::open(Some(path), None) + } else { + S::open(None, None) // this must mean we're using an in-memory storage + }?; + + if let Some(block_num) = storage.get(COL_META, KEY_BEST_BLOCK_NUMBER.as_bytes())? { + if bytes_to_u32(&block_num) != 0 { + return Err(LedgerError::ExistingDatabase.into()); + } + } + + let leaves: &[[u8; 32]] = &[]; + let empty_cm_merkle_tree = MerkleTree::::new(parameters.clone(), leaves)?; + + let ledger_storage = Self { + current_block_height: Default::default(), + storage, + cm_merkle_tree: RwLock::new(empty_cm_merkle_tree), + ledger_parameters: parameters, + _transaction: PhantomData, + }; + + ledger_storage.insert_and_commit(&genesis_block)?; + + Ok(ledger_storage) + } + + /// Returns the number of blocks including the genesis block + fn len(&self) -> usize { + self.get_current_block_height() as usize + 1 + } + + /// Return the parameters used to construct the ledger Merkle tree. + fn parameters(&self) -> &Arc { + &self.ledger_parameters + } + + /// Return a digest of the latest ledger Merkle tree. + fn digest(&self) -> Option { + let digest: Self::MerkleTreeDigest = FromBytes::read(&self.current_digest().unwrap()[..]).unwrap(); + Some(digest) + } + + /// Check that st_{ts} is a valid digest for some (past) ledger state. + fn validate_digest(&self, digest: &Self::MerkleTreeDigest) -> bool { + self.storage.exists(COL_DIGEST, &to_bytes![digest].unwrap()) + } + + /// Returns true if the given commitment exists in the ledger. + fn contains_cm(&self, cm: &Self::Commitment) -> bool { + self.storage.exists(COL_COMMITMENT, &to_bytes![cm].unwrap()) + } + + /// Returns true if the given serial number exists in the ledger. + fn contains_sn(&self, sn: &Self::SerialNumber) -> bool { + self.storage.exists(COL_SERIAL_NUMBER, &to_bytes![sn].unwrap()) + } + + /// Returns true if the given memo exists in the ledger. + fn contains_memo(&self, memo: &::Memorandum) -> bool { + self.storage.exists(COL_MEMO, &to_bytes![memo].unwrap()) + } + + /// Returns the Merkle path to the latest ledger digest + /// for a given commitment, if it exists in the ledger. + fn prove_cm(&self, cm: &Self::Commitment) -> anyhow::Result { + let cm_index = self.get_cm_index(&to_bytes![cm]?)?.ok_or(LedgerError::InvalidCmIndex)?; + let result = self.cm_merkle_tree.read().generate_proof(cm_index, cm)?; + + Ok(result) + } + + /// Returns true if the given Merkle path is a valid witness for + /// the given ledger digest and commitment. + fn verify_cm( + _parameters: &Arc, + digest: &Self::MerkleTreeDigest, + cm: &Self::Commitment, + witness: &Self::MerklePath, + ) -> bool { + witness.verify(&digest, cm).unwrap() + } +} + +impl Ledger { + /// Commit a transaction to the canon chain + #[allow(clippy::type_complexity)] + pub(crate) fn commit_transaction( + &self, + sn_index: &mut usize, + cm_index: &mut usize, + memo_index: &mut usize, + transaction: &T, + ) -> Result<(Vec, Vec<(T::Commitment, usize)>), StorageError> { + let old_serial_numbers = transaction.old_serial_numbers(); + let new_commitments = transaction.new_commitments(); + + let mut ops = Vec::with_capacity(old_serial_numbers.len() + new_commitments.len()); + let mut cms = Vec::with_capacity(new_commitments.len()); + + for sn in old_serial_numbers { + let sn_bytes = to_bytes![sn]?; + if self.get_sn_index(&sn_bytes)?.is_some() { + return Err(StorageError::ExistingSn(sn_bytes.to_vec())); + } + + ops.push(Op::Insert { + col: COL_SERIAL_NUMBER, + key: sn_bytes, + value: (*sn_index as u32).to_le_bytes().to_vec(), + }); + *sn_index += 1; + } + + for cm in new_commitments { + let cm_bytes = to_bytes![cm]?; + if self.get_cm_index(&cm_bytes)?.is_some() { + return Err(StorageError::ExistingCm(cm_bytes.to_vec())); + } + + ops.push(Op::Insert { + col: COL_COMMITMENT, + key: cm_bytes, + value: (*cm_index as u32).to_le_bytes().to_vec(), + }); + cms.push((cm.clone(), *cm_index)); + + *cm_index += 1; + } + + let memo_bytes = to_bytes![transaction.memorandum()]?; + if self.get_memo_index(&memo_bytes)?.is_some() { + return Err(StorageError::ExistingMemo(memo_bytes.to_vec())); + } else { + ops.push(Op::Insert { + col: COL_MEMO, + key: memo_bytes, + value: (*memo_index as u32).to_le_bytes().to_vec(), + }); + *memo_index += 1; + } + + Ok((ops, cms)) + } + + /// Insert a block into storage without canonizing/committing it. + pub fn insert_only(&self, block: &Block) -> Result<(), StorageError> { + let block_hash = block.header.get_hash(); + + // Check that the block does not already exist. + if self.block_hash_exists(&block_hash) { + return Err(StorageError::BlockError(BlockError::BlockExists( + block_hash.to_string(), + ))); + } + + let mut database_transaction = DatabaseTransaction::new(); + + let mut transaction_serial_numbers = Vec::with_capacity(block.transactions.0.len()); + let mut transaction_commitments = Vec::with_capacity(block.transactions.0.len()); + let mut transaction_memos = Vec::with_capacity(block.transactions.0.len()); + + for transaction in &block.transactions.0 { + transaction_serial_numbers.push(transaction.transaction_id()?); + transaction_commitments.push(transaction.new_commitments()); + transaction_memos.push(transaction.memorandum()); + } + + // Sanitize the block inputs + + // Check if the transactions in the block have duplicate serial numbers + if has_duplicates(transaction_serial_numbers) { + return Err(StorageError::DuplicateSn); + } + + // Check if the transactions in the block have duplicate commitments + if has_duplicates(transaction_commitments) { + return Err(StorageError::DuplicateCm); + } + + // Check if the transactions in the block have duplicate memos + if has_duplicates(transaction_memos) { + return Err(StorageError::DuplicateMemo); + } + + for (index, transaction) in block.transactions.0.iter().enumerate() { + let transaction_location = TransactionLocation { + index: index as u32, + block_hash: block.header.get_hash().0, + }; + database_transaction.push(Op::Insert { + col: COL_TRANSACTION_LOCATION, + key: transaction.transaction_id()?.to_vec(), + value: to_bytes![transaction_location]?.to_vec(), + }); + } + + database_transaction.push(Op::Insert { + col: COL_BLOCK_HEADER, + key: block_hash.0.to_vec(), + value: to_bytes![block.header]?.to_vec(), + }); + database_transaction.push(Op::Insert { + col: COL_BLOCK_TRANSACTIONS, + key: block.header.get_hash().0.to_vec(), + value: to_bytes![block.transactions]?.to_vec(), + }); + + let mut child_hashes = self.get_child_block_hashes(&block.header.previous_block_hash)?; + + if !child_hashes.contains(&block_hash) { + child_hashes.push(block_hash); + + database_transaction.push(Op::Insert { + col: COL_CHILD_HASHES, + key: block.header.previous_block_hash.0.to_vec(), + value: bincode::serialize(&child_hashes)?, + }); + } + + database_transaction.push(Op::Insert { + col: COL_BLOCK_TRANSACTIONS, + key: block.header.get_hash().0.to_vec(), + value: to_bytes![block.transactions]?.to_vec(), + }); + + self.storage.batch(database_transaction)?; + + Ok(()) + } + + /// Commit/canonize a particular block. + pub fn commit(&self, block: &Block) -> Result<(), StorageError> { + let block_header_hash = block.header.get_hash(); + + // Check if the block is already in the canon chain + if self.is_canon(&block_header_hash) { + return Err(StorageError::ExistingCanonBlock(block_header_hash.to_string())); + } + + let mut database_transaction = DatabaseTransaction::new(); + + let mut transaction_serial_numbers = Vec::with_capacity(block.transactions.0.len()); + let mut transaction_commitments = Vec::with_capacity(block.transactions.0.len()); + let mut transaction_memos = Vec::with_capacity(block.transactions.0.len()); + + for transaction in &block.transactions.0 { + transaction_serial_numbers.push(transaction.transaction_id()?); + transaction_commitments.push(transaction.new_commitments()); + transaction_memos.push(transaction.memorandum()); + } + + // Sanitize the block inputs + + // Check if the transactions in the block have duplicate serial numbers + if has_duplicates(transaction_serial_numbers) { + return Err(StorageError::DuplicateSn); + } + + // Check if the transactions in the block have duplicate commitments + if has_duplicates(transaction_commitments) { + return Err(StorageError::DuplicateCm); + } + + // Check if the transactions in the block have duplicate memos + if has_duplicates(transaction_memos) { + return Err(StorageError::DuplicateMemo); + } + + let mut sn_index = self.current_sn_index()?; + let mut cm_index = self.current_cm_index()?; + let mut memo_index = self.current_memo_index()?; + + // Process the individual transactions + + let mut transaction_cms = vec![]; + + for transaction in block.transactions.0.iter() { + let (tx_ops, cms) = self.commit_transaction(&mut sn_index, &mut cm_index, &mut memo_index, transaction)?; + database_transaction.push_vec(tx_ops); + transaction_cms.extend(cms); + } + + // Update the database state for current indexes + + database_transaction.push(Op::Insert { + col: COL_META, + key: KEY_CURR_SN_INDEX.as_bytes().to_vec(), + value: (sn_index as u32).to_le_bytes().to_vec(), + }); + database_transaction.push(Op::Insert { + col: COL_META, + key: KEY_CURR_CM_INDEX.as_bytes().to_vec(), + value: (cm_index as u32).to_le_bytes().to_vec(), + }); + database_transaction.push(Op::Insert { + col: COL_META, + key: KEY_CURR_MEMO_INDEX.as_bytes().to_vec(), + value: (memo_index as u32).to_le_bytes().to_vec(), + }); + + // Update the best block number + + let height = self.get_current_block_height(); + + let is_genesis = + block.header.previous_block_hash == BlockHeaderHash([0u8; 32]) && height == 0 && self.is_empty(); + + let mut new_best_block_number = 0; + if !is_genesis { + new_best_block_number = height + 1; + } + + database_transaction.push(Op::Insert { + col: COL_META, + key: KEY_BEST_BLOCK_NUMBER.as_bytes().to_vec(), + value: new_best_block_number.to_le_bytes().to_vec(), + }); + + // Update the block location + + database_transaction.push(Op::Insert { + col: COL_BLOCK_LOCATOR, + key: block.header.get_hash().0.to_vec(), + value: new_best_block_number.to_le_bytes().to_vec(), + }); + database_transaction.push(Op::Insert { + col: COL_BLOCK_LOCATOR, + key: new_best_block_number.to_le_bytes().to_vec(), + value: block.header.get_hash().0.to_vec(), + }); + + // Rebuild the new commitment merkle tree + self.rebuild_merkle_tree(transaction_cms)?; + let new_digest = self.cm_merkle_tree.read().root(); + + database_transaction.push(Op::Insert { + col: COL_DIGEST, + key: to_bytes![new_digest]?.to_vec(), + value: new_best_block_number.to_le_bytes().to_vec(), + }); + database_transaction.push(Op::Insert { + col: COL_META, + key: KEY_CURR_DIGEST.as_bytes().to_vec(), + value: to_bytes![new_digest]?.to_vec(), + }); + + self.storage.batch(database_transaction)?; + + if !is_genesis { + self.current_block_height.fetch_add(1, Ordering::SeqCst); + } + + Ok(()) + } + + /// Insert a block into the storage and commit as part of the longest chain. + pub fn insert_and_commit(&self, block: &Block) -> Result<(), StorageError> { + let block_hash = block.header.get_hash(); + + // If the block does not exist in the storage + if !self.block_hash_exists(&block_hash) { + // Insert it first + self.insert_only(&block)?; + } + // Commit it + self.commit(block) + } + + /// Returns true if the block exists in the canon chain. + pub fn is_canon(&self, block_hash: &BlockHeaderHash) -> bool { + self.block_hash_exists(block_hash) && self.get_block_number(block_hash).is_ok() + } +} diff --git a/.snarkos-integration/src/lib.rs b/.snarkos-integration/src/lib.rs new file mode 100644 index 0000000000..83e798c2d4 --- /dev/null +++ b/.snarkos-integration/src/lib.rs @@ -0,0 +1,87 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the snarkVM library. + +// The snarkVM library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The snarkVM library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the snarkVM library. If not, see . + +use snarkvm_utilities::bytes::{FromBytes, ToBytes}; + +use std::io::{Read, Result as IoResult, Write}; + +pub const COL_META: u32 = 0; // MISC Values +pub const COL_BLOCK_HEADER: u32 = 1; // Block hash -> block header +pub const COL_BLOCK_TRANSACTIONS: u32 = 2; // Block hash -> block transactions +pub const COL_BLOCK_LOCATOR: u32 = 3; // Block num -> block hash && block hash -> block num +pub const COL_TRANSACTION_LOCATION: u32 = 4; // Transaction Hash -> (block hash and index) +pub const COL_COMMITMENT: u32 = 5; // Commitment -> index +pub const COL_SERIAL_NUMBER: u32 = 6; // SN -> index +pub const COL_MEMO: u32 = 7; // Memo -> index +pub const COL_DIGEST: u32 = 8; // Ledger digest -> index +pub const COL_RECORDS: u32 = 9; // commitment -> record bytes +pub const COL_CHILD_HASHES: u32 = 10; // block hash -> vector of potential child hashes +pub const NUM_COLS: u32 = 11; + +pub const KEY_BEST_BLOCK_NUMBER: &str = "BEST_BLOCK_NUMBER"; +pub const KEY_MEMORY_POOL: &str = "MEMORY_POOL"; +pub const KEY_PEER_BOOK: &str = "PEER_BOOK"; + +pub const KEY_CURR_CM_INDEX: &str = "CURRENT_CM_INDEX"; +pub const KEY_CURR_SN_INDEX: &str = "CURRENT_SN_INDEX"; +pub const KEY_CURR_MEMO_INDEX: &str = "CURRENT_MEMO_INDEX"; +pub const KEY_CURR_DIGEST: &str = "CURRENT_DIGEST"; + +pub mod dpc; +pub use dpc::*; + +pub mod ledger; +pub use ledger::*; + +pub mod memdb; +pub use memdb::*; + +pub mod storage; +pub use storage::*; + +/// Represents address of certain transaction within block +#[derive(Debug, PartialEq, Clone)] +pub struct TransactionLocation { + /// Transaction index within the block + pub index: u32, + /// Block hash + pub block_hash: [u8; 32], +} + +impl ToBytes for TransactionLocation { + #[inline] + fn write(&self, mut writer: W) -> IoResult<()> { + self.index.write(&mut writer)?; + self.block_hash.write(&mut writer) + } +} + +impl FromBytes for TransactionLocation { + #[inline] + fn read(mut reader: R) -> IoResult { + let index: u32 = FromBytes::read(&mut reader)?; + let block_hash: [u8; 32] = FromBytes::read(&mut reader)?; + + Ok(Self { index, block_hash }) + } +} + +pub fn bytes_to_u32(bytes: &[u8]) -> u32 { + let mut num_bytes = [0u8; 4]; + num_bytes.copy_from_slice(&bytes); + + u32::from_le_bytes(num_bytes) +} diff --git a/.snarkos-integration/src/memdb.rs b/.snarkos-integration/src/memdb.rs new file mode 100644 index 0000000000..e266dc8a65 --- /dev/null +++ b/.snarkos-integration/src/memdb.rs @@ -0,0 +1,86 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the snarkVM library. + +// The snarkVM library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The snarkVM library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the snarkVM library. If not, see . + +use crate::NUM_COLS; +use snarkvm_dpc::prelude::*; + +use parking_lot::RwLock; + +use std::{collections::HashMap, path::Path}; + +#[allow(clippy::type_complexity)] +pub struct MemDb { + pub cols: RwLock, Box<[u8]>>>>, +} + +impl Storage for MemDb { + const IN_MEMORY: bool = true; + + fn open(_path: Option<&Path>, _secondary_path: Option<&Path>) -> Result { + // the paths are just ignored + + Ok(Self { + cols: RwLock::new(vec![Default::default(); NUM_COLS as usize]), + }) + } + + fn get(&self, col: u32, key: &[u8]) -> Result>, StorageError> { + Ok(self.cols.read()[col as usize].get(key).map(|v| v.to_vec())) + } + + #[allow(clippy::type_complexity)] + fn get_col(&self, col: u32) -> Result, Box<[u8]>)>, StorageError> { + Ok(self.cols.read()[col as usize].clone().into_iter().collect()) + } + + fn get_keys(&self, col: u32) -> Result>, StorageError> { + Ok(self.cols.read()[col as usize].keys().cloned().collect()) + } + + fn put, V: AsRef<[u8]>>(&self, col: u32, key: K, value: V) -> Result<(), StorageError> { + self.cols.write()[col as usize].insert(key.as_ref().into(), value.as_ref().into()); + Ok(()) + } + + fn batch(&self, transaction: DatabaseTransaction) -> Result<(), StorageError> { + if transaction.0.is_empty() { + return Ok(()); + } + + let mut cols = self.cols.write(); + for operation in transaction.0 { + match operation { + Op::Insert { col, key, value } => { + cols[col as usize].insert(key.into(), value.into()); + } + Op::Delete { col, key } => { + cols[col as usize].remove(&Box::from(key)); + } + } + } + + Ok(()) + } + + fn exists(&self, col: u32, key: &[u8]) -> bool { + self.cols.read()[col as usize].contains_key(key) + } + + fn try_catch_up_with_primary(&self) -> Result<(), StorageError> { + // used only in Ledger::catch_up_secondary, doesn't cause an early return + Err(StorageError::Message("MemDb has no secondary instance".into())) + } +} diff --git a/.snarkos-integration/src/storage.rs b/.snarkos-integration/src/storage.rs new file mode 100644 index 0000000000..218545a439 --- /dev/null +++ b/.snarkos-integration/src/storage.rs @@ -0,0 +1,124 @@ +// Copyright (C) 2019-2021 Aleo Systems Inc. +// This file is part of the snarkVM library. + +// The snarkVM library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The snarkVM library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the snarkVM library. If not, see . + +use crate::{memdb::MemDb, Ledger}; +use snarkvm_algorithms::traits::merkle_tree::LoadableMerkleParameters; +use snarkvm_dpc::{ + block::Block, + testnet1::instantiated::CommitmentMerkleParameters, + traits::{BlockScheme, LedgerScheme, Storage, TransactionScheme}, + TransactionError, +}; +use snarkvm_utilities::{FromBytes, ToBytes}; + +use rand::{thread_rng, Rng}; +use std::{ + io::{Read, Result as IoResult, Write}, + sync::Arc, +}; + +pub fn random_storage_path() -> String { + let random_path: usize = thread_rng().gen(); + format!("./test_db-{}", random_path) +} + +// Initialize a test blockchain given genesis attributes +pub fn initialize_test_blockchain( + parameters: Arc

, + genesis_block: Block, +) -> Ledger { + let mut path = std::env::temp_dir(); + path.push(random_storage_path()); + + Ledger::::new(Some(&path), parameters, genesis_block).unwrap() +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TestTx; + +impl TransactionScheme for TestTx { + type Commitment = [u8; 32]; + type Digest = [u8; 32]; + type EncryptedRecord = [u8; 32]; + type InnerCircuitID = [u8; 32]; + type LocalDataRoot = [u8; 32]; + type Memorandum = [u8; 32]; + type ProgramCommitment = [u8; 32]; + type SerialNumber = [u8; 32]; + type ValueBalance = i64; + + fn transaction_id(&self) -> Result<[u8; 32], TransactionError> { + Ok([0u8; 32]) + } + + fn network_id(&self) -> u8 { + 0 + } + + fn ledger_digest(&self) -> &Self::Digest { + &[0u8; 32] + } + + fn inner_circuit_id(&self) -> &Self::InnerCircuitID { + &[0u8; 32] + } + + fn old_serial_numbers(&self) -> &[Self::SerialNumber] { + &[[0u8; 32]] + } + + fn new_commitments(&self) -> &[Self::Commitment] { + &[[0u8; 32]] + } + + fn program_commitment(&self) -> &Self::ProgramCommitment { + &[0u8; 32] + } + + fn local_data_root(&self) -> &Self::LocalDataRoot { + &[0u8; 32] + } + + fn value_balance(&self) -> i64 { + 0 + } + + fn memorandum(&self) -> &Self::Memorandum { + &[0u8; 32] + } + + fn encrypted_records(&self) -> &[Self::EncryptedRecord] { + &[[0u8; 32]] + } + + fn size(&self) -> usize { + 0 + } +} + +impl ToBytes for TestTx { + #[inline] + fn write(&self, mut _writer: W) -> IoResult<()> { + Ok(()) + } +} + +impl FromBytes for TestTx { + #[inline] + fn read(mut _reader: R) -> IoResult { + Ok(Self) + } +} diff --git a/.snarkos-integration/tests/base_dpc.rs b/.snarkos-integration/tests/dpc_testnet1.rs similarity index 94% rename from .snarkos-integration/tests/base_dpc.rs rename to .snarkos-integration/tests/dpc_testnet1.rs index b64d1d0d96..2e0d91d57c 100644 --- a/.snarkos-integration/tests/base_dpc.rs +++ b/.snarkos-integration/tests/dpc_testnet1.rs @@ -14,41 +14,27 @@ // You should have received a copy of the GNU General Public License // along with the snarkVM library. If not, see . -use snarkos_storage::mem::MemDb; -use snarkos_testing::{dpc::*, storage::*}; use snarkvm_algorithms::{ merkle_tree::MerklePath, traits::{MerkleParameters, CRH, SNARK}, }; use snarkvm_curves::bls12_377::{Fq, Fr}; use snarkvm_dpc::{ - account::{Account, AccountViewKey}, - base_dpc::{ + prelude::*, + testnet1::{ execute_inner_proof_gadget, execute_outer_proof_gadget, inner_circuit::InnerCircuit, instantiated::*, parameters::{NoopProgramSNARKParameters, SystemParameters}, program::NoopProgram, - record::record_encryption::RecordEncryption, - record_payload::RecordPayload, + record::{payload::Payload, record_encryption::RecordEncryption}, BaseDPCComponents, TransactionKernel, DPC, }, - traits::{AccountScheme, DPCScheme, Program, Record}, -}; -use snarkvm_objects::{ - dpc::DPCTransactions, - merkle_root, - traits::{LedgerScheme, Transaction}, - Block, - BlockHeader, - BlockHeaderHash, - MerkleRootHash, - PedersenMerkleRootHash, - ProofOfSuccinctWork, }; +use snarkvm_integration::{dpc::*, ledger::*, memdb::MemDb, storage::*}; use snarkvm_r1cs::{ConstraintSystem, TestConstraintSystem}; use snarkvm_utilities::{ bytes::{FromBytes, ToBytes}, @@ -66,7 +52,7 @@ use std::{ type L = Ledger; #[test] -fn base_dpc_integration_test() { +fn dpc_testnet1_integration_test() { let mut rng = XorShiftRng::seed_from_u64(1231275789u64); // Generate or load parameters for the ledger, commitment schemes, and CRH @@ -88,9 +74,9 @@ fn base_dpc_integration_test() { time: 0, difficulty_target: 0x07FF_FFFF_FFFF_FFFF_u64, nonce: 0, - proof: ProofOfSuccinctWork::default(), + proof: ProofOfSuccinctWork([0u8; 972]), }, - transactions: DPCTransactions::new(), + transactions: Transactions::new(), }; let ledger = initialize_test_blockchain::(ledger_parameters, genesis_block); @@ -119,7 +105,7 @@ fn base_dpc_integration_test() { genesis_account.address.clone(), true, // The input record is dummy 0, - RecordPayload::default(), + Payload::default(), noop_program_id.clone(), noop_program_id.clone(), &mut rng, @@ -134,7 +120,7 @@ fn base_dpc_integration_test() { let new_record_owners = vec![recipient.address.clone(); NUM_OUTPUT_RECORDS]; let new_is_dummy_flags = vec![false; NUM_OUTPUT_RECORDS]; let new_values = vec![10; NUM_OUTPUT_RECORDS]; - let new_payloads = vec![RecordPayload::default(); NUM_OUTPUT_RECORDS]; + let new_payloads = vec![Payload::default(); NUM_OUTPUT_RECORDS]; let new_birth_program_ids = vec![noop_program_id.clone(); NUM_OUTPUT_RECORDS]; let new_death_program_ids = vec![noop_program_id.clone(); NUM_OUTPUT_RECORDS]; @@ -237,7 +223,7 @@ fn base_dpc_integration_test() { let previous_block = ledger.get_latest_block().unwrap(); - let mut transactions = DPCTransactions::new(); + let mut transactions = Transactions::new(); transactions.push(transaction); let transaction_ids = transactions.to_transaction_ids().unwrap(); @@ -257,7 +243,7 @@ fn base_dpc_integration_test() { difficulty_target: previous_block.header.difficulty_target, nonce: 0, pedersen_merkle_root_hash: PedersenMerkleRootHash([0u8; 32]), - proof: ProofOfSuccinctWork::default(), + proof: ProofOfSuccinctWork([0u8; 972]), }; assert!(InstantiatedDPC::verify_transactions(¶meters, &transactions.0, &ledger).unwrap()); @@ -314,7 +300,7 @@ fn test_transaction_kernel_serialization() { test_account.address.clone(), true, 0, - RecordPayload::default(), + Payload::default(), noop_program_id.clone(), noop_program_id.clone(), &mut rng, @@ -330,7 +316,7 @@ fn test_transaction_kernel_serialization() { let new_record_owners = vec![test_account.address; NUM_OUTPUT_RECORDS]; let new_is_dummy_flags = vec![false; NUM_OUTPUT_RECORDS]; let new_values = vec![10; NUM_OUTPUT_RECORDS]; - let new_payloads = vec![RecordPayload::default(); NUM_OUTPUT_RECORDS]; + let new_payloads = vec![Payload::default(); NUM_OUTPUT_RECORDS]; let new_birth_program_ids = vec![noop_program_id.clone(); NUM_OUTPUT_RECORDS]; let new_death_program_ids = vec![noop_program_id; NUM_OUTPUT_RECORDS]; let memo = [0u8; 32]; @@ -398,9 +384,9 @@ fn test_execute_base_dpc_constraints() { difficulty_target: 0x07FF_FFFF_FFFF_FFFF_u64, nonce: 0, pedersen_merkle_root_hash: PedersenMerkleRootHash([0u8; 32]), - proof: ProofOfSuccinctWork::default(), + proof: ProofOfSuccinctWork([0u8; 972]), }, - transactions: DPCTransactions::new(), + transactions: Transactions::new(), }; // Use genesis record, serial number, and memo to initialize the ledger. @@ -413,7 +399,7 @@ fn test_execute_base_dpc_constraints() { dummy_account.address, true, 0, - RecordPayload::default(), + Payload::default(), alternate_noop_program_id.clone(), alternate_noop_program_id.clone(), &mut rng, @@ -441,7 +427,7 @@ fn test_execute_base_dpc_constraints() { let new_record_owners = vec![new_account.address; NUM_OUTPUT_RECORDS]; let new_is_dummy_flags = vec![false; NUM_OUTPUT_RECORDS]; let new_values = vec![10; NUM_OUTPUT_RECORDS]; - let new_payloads = vec![RecordPayload::default(); NUM_OUTPUT_RECORDS]; + let new_payloads = vec![Payload::default(); NUM_OUTPUT_RECORDS]; let new_birth_program_ids = vec![noop_program_id.clone(); NUM_OUTPUT_RECORDS]; let new_death_program_ids = vec![noop_program_id.clone(); NUM_OUTPUT_RECORDS]; let memo = [0u8; 32]; @@ -608,11 +594,11 @@ fn test_execute_base_dpc_constraints() { ) .unwrap(); - let inner_snark_vk: <::InnerSNARK as SNARK>::VerificationParameters = + let inner_snark_vk: <::InnerSNARK as SNARK>::VerifyingKey = inner_snark_parameters.1.clone().into(); - let inner_snark_id = InnerSNARKVerificationKeyCRH::hash( - &system_parameters.inner_snark_verification_key_crh, + let inner_snark_id = InnerCircuitIDCRH::hash( + &system_parameters.inner_circuit_id_crh, &to_bytes![inner_snark_vk].unwrap(), ) .unwrap(); diff --git a/Cargo.lock b/Cargo.lock index 8718b0df4b..89ad9f405b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1569,87 +1569,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" -[[package]] -name = "snarkos-consensus" -version = "1.3.6" -source = "git+https://github.com/AleoHQ/snarkOS?rev=e72d3d9d03d1a053ae148608e3f5b3ae857a4edf#e72d3d9d03d1a053ae148608e3f5b3ae857a4edf" -dependencies = [ - "anyhow", - "chrono", - "hex", - "parking_lot", - "rand", - "snarkos-profiler", - "snarkos-storage", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-dpc 0.3.2", - "snarkvm-objects", - "snarkvm-posw 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", - "tracing", -] - -[[package]] -name = "snarkos-parameters" -version = "1.3.6" -source = "git+https://github.com/AleoHQ/snarkOS?rev=e72d3d9d03d1a053ae148608e3f5b3ae857a4edf#e72d3d9d03d1a053ae148608e3f5b3ae857a4edf" -dependencies = [ - "curl", - "snarkvm-algorithms 0.3.2", - "snarkvm-parameters 0.3.2", - "snarkvm-utilities 0.3.2", -] - -[[package]] -name = "snarkos-profiler" -version = "1.3.6" -source = "git+https://github.com/AleoHQ/snarkOS?rev=e72d3d9d03d1a053ae148608e3f5b3ae857a4edf#e72d3d9d03d1a053ae148608e3f5b3ae857a4edf" - -[[package]] -name = "snarkos-storage" -version = "1.3.6" -source = "git+https://github.com/AleoHQ/snarkOS?rev=e72d3d9d03d1a053ae148608e3f5b3ae857a4edf#e72d3d9d03d1a053ae148608e3f5b3ae857a4edf" -dependencies = [ - "anyhow", - "bincode", - "hex", - "parking_lot", - "rand", - "serde", - "snarkos-parameters", - "snarkvm-algorithms 0.3.2", - "snarkvm-dpc 0.3.2", - "snarkvm-objects", - "snarkvm-parameters 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", -] - -[[package]] -name = "snarkos-testing" -version = "1.3.6" -source = "git+https://github.com/AleoHQ/snarkOS?rev=e72d3d9d03d1a053ae148608e3f5b3ae857a4edf#e72d3d9d03d1a053ae148608e3f5b3ae857a4edf" -dependencies = [ - "anyhow", - "bincode", - "once_cell", - "parking_lot", - "rand", - "rand_xorshift", - "snarkos-consensus", - "snarkos-parameters", - "snarkos-storage", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-dpc 0.3.2", - "snarkvm-objects", - "snarkvm-parameters 0.3.2", - "snarkvm-posw 0.3.2", - "snarkvm-utilities 0.3.2", -] - [[package]] name = "snarkvm" version = "0.4.0" @@ -1662,30 +1581,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "snarkvm-algorithms" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e91c38fc466c78982838e6791b6548ff1c3a501f85ff99c9df26bd2b7c31df" -dependencies = [ - "bitvec", - "blake2", - "derivative", - "digest", - "itertools 0.10.0", - "rand", - "rand_chacha", - "rayon", - "sha2", - "smallvec", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-profiler 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", -] - [[package]] name = "snarkvm-algorithms" version = "0.4.0" @@ -1703,27 +1598,11 @@ dependencies = [ "rayon", "sha2", "smallvec", - "snarkvm-curves 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-profiler 0.4.0", - "snarkvm-r1cs 0.4.0", - "snarkvm-utilities 0.4.0", - "thiserror", -] - -[[package]] -name = "snarkvm-curves" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c21ece50ccbc9fff720f331600d3d4cea601a85d65c7edcf0523b0c0d9ed546" -dependencies = [ - "derivative", - "rand", - "rand_xorshift", - "rustc_version", - "serde", - "snarkvm-fields 0.3.2", - "snarkvm-utilities 0.3.2", + "snarkvm-curves", + "snarkvm-fields", + "snarkvm-profiler", + "snarkvm-r1cs", + "snarkvm-utilities", "thiserror", ] @@ -1737,24 +1616,11 @@ dependencies = [ "rand_xorshift", "rustc_version", "serde", - "snarkvm-fields 0.4.0", - "snarkvm-utilities 0.4.0", + "snarkvm-fields", + "snarkvm-utilities", "thiserror", ] -[[package]] -name = "snarkvm-derives" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "997867488de79265129e8828cce65c6375a8b12579c319a4c11f0e96b15b38e1" -dependencies = [ - "proc-macro-crate", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "snarkvm-derives" version = "0.4.0" @@ -1766,32 +1632,6 @@ dependencies = [ "syn", ] -[[package]] -name = "snarkvm-dpc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99753250e10687bbef8896d74f2a2057152b8f7cb98c522bcd548d243a59a5f2" -dependencies = [ - "anyhow", - "base58", - "bech32", - "blake2", - "derivative", - "hex", - "itertools 0.10.0", - "rand", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-gadgets 0.3.2", - "snarkvm-objects", - "snarkvm-parameters 0.3.2", - "snarkvm-profiler 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", -] - [[package]] name = "snarkvm-dpc" version = "0.4.0" @@ -1810,29 +1650,14 @@ dependencies = [ "rand_xorshift", "serde", "sha2", - "snarkvm-algorithms 0.4.0", - "snarkvm-curves 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-gadgets 0.4.0", - "snarkvm-parameters 0.4.0", - "snarkvm-profiler 0.4.0", - "snarkvm-r1cs 0.4.0", - "snarkvm-utilities 0.4.0", - "thiserror", -] - -[[package]] -name = "snarkvm-fields" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca55c160a05cc017344364583bf338f7c0b0529b2a3e352b3290158eacc58c04" -dependencies = [ - "bincode", - "derivative", - "rand", - "rand_xorshift", - "serde", - "snarkvm-utilities 0.3.2", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-fields", + "snarkvm-gadgets", + "snarkvm-parameters", + "snarkvm-profiler", + "snarkvm-r1cs", + "snarkvm-utilities", "thiserror", ] @@ -1845,24 +1670,7 @@ dependencies = [ "rand", "rand_xorshift", "serde", - "snarkvm-utilities 0.4.0", - "thiserror", -] - -[[package]] -name = "snarkvm-gadgets" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a16ea5c90c431844d9f15e86dee96d1de9c67cafa6daece0b953cba46b688ded" -dependencies = [ - "derivative", - "digest", - "itertools 0.10.0", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", + "snarkvm-utilities", "thiserror", ] @@ -1881,37 +1689,39 @@ dependencies = [ "paste", "rand", "rand_xorshift", - "snarkvm-algorithms 0.4.0", - "snarkvm-curves 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-r1cs 0.4.0", - "snarkvm-utilities 0.4.0", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-fields", + "snarkvm-r1cs", + "snarkvm-utilities", "thiserror", ] [[package]] -name = "snarkvm-marlin" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495665f83fc381e8298dc13c14cddb5a93fa083a66ade85d16a009b6e05162d6" +name = "snarkvm-integration" +version = "0.4.0" dependencies = [ + "anyhow", + "base58", + "bech32", + "bincode", "blake2", "derivative", - "digest", - "hashbrown 0.11.2", + "hex", + "itertools 0.10.0", + "parking_lot", "rand", - "rand_chacha", - "rand_core", - "rayon", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-gadgets 0.3.2", - "snarkvm-nonnative", - "snarkvm-polycommit 0.3.2", - "snarkvm-profiler 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", + "rand_xorshift", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-dpc", + "snarkvm-fields", + "snarkvm-gadgets", + "snarkvm-parameters", + "snarkvm-profiler", + "snarkvm-r1cs", + "snarkvm-utilities", + "thiserror", ] [[package]] @@ -1927,65 +1737,14 @@ dependencies = [ "rand_chacha", "rand_core", "rayon", - "snarkvm-algorithms 0.4.0", - "snarkvm-curves 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-gadgets 0.4.0", - "snarkvm-polycommit 0.4.0", - "snarkvm-profiler 0.4.0", - "snarkvm-r1cs 0.4.0", - "snarkvm-utilities 0.4.0", -] - -[[package]] -name = "snarkvm-nonnative" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f100b88bff1a874e70754b20d40b5e95f151995f6c6715757a1ffaa8b626a2" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-gadgets 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", -] - -[[package]] -name = "snarkvm-objects" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "751579a470a747d924f99a3ea6e14e23ec30f3586845303620ec7900b663b4da" -dependencies = [ - "anyhow", - "bincode", - "chrono", - "hex", - "once_cell", - "rand", - "serde", - "sha2", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-parameters 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", -] - -[[package]] -name = "snarkvm-parameters" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc627efbdd7f7d053bdf545782e34eb442574cdb2edc324c0fd8658a5e4343c4" -dependencies = [ - "curl", - "hex", - "snarkvm-algorithms 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-fields", + "snarkvm-gadgets", + "snarkvm-polycommit", + "snarkvm-profiler", + "snarkvm-r1cs", + "snarkvm-utilities", ] [[package]] @@ -1996,36 +1755,16 @@ dependencies = [ "curl", "hex", "rand", - "snarkvm-algorithms 0.4.0", - "snarkvm-curves 0.4.0", - "snarkvm-dpc 0.4.0", - "snarkvm-marlin 0.4.0", - "snarkvm-polycommit 0.4.0", - "snarkvm-posw 0.4.0", - "snarkvm-utilities 0.4.0", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-dpc", + "snarkvm-marlin", + "snarkvm-polycommit", + "snarkvm-posw", + "snarkvm-utilities", "thiserror", ] -[[package]] -name = "snarkvm-polycommit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb9ec9b1b0b31093974f17014847160cf6d871896e44f8bf98e8db360f77512a" -dependencies = [ - "derivative", - "digest", - "hashbrown 0.11.2", - "rand_core", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-gadgets 0.3.2", - "snarkvm-nonnative", - "snarkvm-profiler 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", -] - [[package]] name = "snarkvm-polycommit" version = "0.4.0" @@ -2037,36 +1776,14 @@ dependencies = [ "rand", "rand_core", "rayon", - "snarkvm-algorithms 0.4.0", - "snarkvm-curves 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-gadgets 0.4.0", - "snarkvm-marlin 0.4.0", - "snarkvm-profiler 0.4.0", - "snarkvm-r1cs 0.4.0", - "snarkvm-utilities 0.4.0", -] - -[[package]] -name = "snarkvm-posw" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88ba66f6b6a2a4e349ecb6d7d68c673b05c9460f9123e674f5fbfe224b63b39" -dependencies = [ - "blake2", - "rand", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-gadgets 0.3.2", - "snarkvm-marlin 0.3.2", - "snarkvm-objects", - "snarkvm-parameters 0.3.2", - "snarkvm-polycommit 0.3.2", - "snarkvm-profiler 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-fields", + "snarkvm-gadgets", + "snarkvm-marlin", + "snarkvm-profiler", + "snarkvm-r1cs", + "snarkvm-utilities", ] [[package]] @@ -2079,26 +1796,20 @@ dependencies = [ "rand", "rand_xorshift", "serde", - "snarkvm-algorithms 0.4.0", - "snarkvm-curves 0.4.0", - "snarkvm-dpc 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-gadgets 0.4.0", - "snarkvm-marlin 0.4.0", - "snarkvm-parameters 0.4.0", - "snarkvm-polycommit 0.4.0", - "snarkvm-profiler 0.4.0", - "snarkvm-r1cs 0.4.0", - "snarkvm-utilities 0.4.0", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-dpc", + "snarkvm-fields", + "snarkvm-gadgets", + "snarkvm-marlin", + "snarkvm-parameters", + "snarkvm-polycommit", + "snarkvm-profiler", + "snarkvm-r1cs", + "snarkvm-utilities", "thiserror", ] -[[package]] -name = "snarkvm-profiler" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf41d4ad2867afa01e0ac06d1ab6eba617de2485b5624090d644a96e975364f" - [[package]] name = "snarkvm-profiler" version = "0.4.0" @@ -2106,21 +1817,6 @@ dependencies = [ "colored", ] -[[package]] -name = "snarkvm-r1cs" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd93405057c715fd8cb207cf3f391faee7eb6dc77c6299e6e482dc428a70dd4b" -dependencies = [ - "cfg-if 1.0.0", - "fxhash", - "indexmap", - "itertools 0.10.0", - "snarkvm-curves 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-utilities 0.3.2", -] - [[package]] name = "snarkvm-r1cs" version = "0.4.0" @@ -2129,49 +1825,9 @@ dependencies = [ "fxhash", "indexmap", "itertools 0.10.0", - "snarkvm-curves 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-utilities 0.4.0", -] - -[[package]] -name = "snarkvm-snarkos-integration" -version = "0.3.1" -dependencies = [ - "anyhow", - "base58", - "bech32", - "blake2", - "derivative", - "hex", - "itertools 0.10.0", - "rand", - "rand_xorshift", - "snarkos-storage", - "snarkos-testing", - "snarkvm-algorithms 0.3.2", - "snarkvm-curves 0.3.2", - "snarkvm-dpc 0.3.2", - "snarkvm-fields 0.3.2", - "snarkvm-gadgets 0.3.2", - "snarkvm-objects", - "snarkvm-parameters 0.3.2", - "snarkvm-profiler 0.3.2", - "snarkvm-r1cs 0.3.2", - "snarkvm-utilities 0.3.2", - "thiserror", -] - -[[package]] -name = "snarkvm-utilities" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5711d92865242115a157a9995c34ff5e25ab86007504b3eaf513dcc1f343cf9" -dependencies = [ - "bincode", - "rand", - "snarkvm-derives 0.3.2", - "thiserror", + "snarkvm-curves", + "snarkvm-fields", + "snarkvm-utilities", ] [[package]] @@ -2181,7 +1837,7 @@ dependencies = [ "bincode", "rand", "rand_xorshift", - "snarkvm-derives 0.4.0", + "snarkvm-derives", "thiserror", ] @@ -2194,13 +1850,13 @@ dependencies = [ "rand", "rand_xorshift", "serde", - "snarkvm-algorithms 0.4.0", - "snarkvm-curves 0.4.0", - "snarkvm-fields 0.4.0", - "snarkvm-gadgets 0.4.0", - "snarkvm-polycommit 0.4.0", - "snarkvm-r1cs 0.4.0", - "snarkvm-utilities 0.4.0", + "snarkvm-algorithms", + "snarkvm-curves", + "snarkvm-fields", + "snarkvm-gadgets", + "snarkvm-polycommit", + "snarkvm-r1cs", + "snarkvm-utilities", "wasm-bindgen", "wasm-bindgen-test", ] @@ -2417,7 +2073,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ "cfg-if 1.0.0", - "log", "pin-project-lite", "tracing-core", ]