diff --git a/.travis.yml b/.travis.yml
index 50d93625..b00ed01f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
dist: trusty
language: go
go:
- - 1.9
+ - 1.11
services:
- postgresql
addons:
diff --git a/Gopkg.lock b/Gopkg.lock
index edf16139..bad46b33 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -117,6 +117,17 @@
revision = "d460ce9f8df2e77fb1ba55ca87fafed96c607494"
version = "v1.0.0"
+[[projects]]
+ branch = "master"
+ digest = "1:9c776d7d9c54b7ed89f119e449983c3f24c0023e75001d6092442412ebca6b94"
+ name = "github.com/hashicorp/golang-lru"
+ packages = [
+ ".",
+ "simplelru",
+ ]
+ pruneopts = ""
+ revision = "0fb14efe8c47ae851c0034ed7a448854d3d34cf3"
+
[[projects]]
digest = "1:d14365c51dd1d34d5c79833ec91413bfbb166be978724f15701e17080dc06dec"
name = "github.com/hashicorp/hcl"
@@ -552,6 +563,7 @@
"github.com/ethereum/go-ethereum/p2p/discv5",
"github.com/ethereum/go-ethereum/params",
"github.com/ethereum/go-ethereum/rpc",
+ "github.com/hashicorp/golang-lru",
"github.com/jmoiron/sqlx",
"github.com/lib/pq",
"github.com/mitchellh/go-homedir",
diff --git a/LICENSE b/LICENSE
index 261eeb9e..331f7cfa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,201 +1,661 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
- 1. Definitions.
+ Preamble
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
+ The GNU Affero General Public License is a free, copyleft license for
+ software and other kinds of works, specifically designed to ensure
+ cooperation with the community in the case of network server software.
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
+ The licenses for most software and other practical works are designed
+ to take away your freedom to share and change the works. By contrast,
+ our General Public Licenses are 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.
- "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.
+ 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.
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
+ Developers that use our General Public Licenses protect your rights
+ with two steps: (1) assert copyright on the software, and (2) offer
+ you this License which gives you legal permission to copy, distribute
+ and/or modify the software.
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
+ A secondary benefit of defending all users' freedom is that
+ improvements made in alternate versions of the program, if they
+ receive widespread use, become available for other developers to
+ incorporate. Many developers of free software are heartened and
+ encouraged by the resulting cooperation. However, in the case of
+ software used on network servers, this result may fail to come about.
+ The GNU General Public License permits making a modified version and
+ letting the public access it on a server without ever releasing its
+ source code to the public.
- "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.
+ The GNU Affero General Public License is designed specifically to
+ ensure that, in such cases, the modified source code becomes available
+ to the community. It requires the operator of a network server to
+ provide the source code of the modified version running there to the
+ users of that server. Therefore, public use of a modified version, on
+ a publicly accessible server, gives the public access to the source
+ code of the modified version.
- "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).
+ An older license, called the Affero General Public License and
+ published by Affero, was designed to accomplish similar goals. This is
+ a different license, not a version of the Affero GPL, but Affero has
+ released a new version of the Affero GPL which permits relicensing under
+ this license.
- "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.
+ The precise terms and conditions for copying, distribution and
+ modification follow.
- "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."
+ TERMS AND CONDITIONS
- "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.
+ 0. Definitions.
- 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.
+ "This License" refers to version 3 of the GNU Affero General Public License.
- 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.
+ "Copyright" also means copyright-like laws that apply to other kinds of
+ works, such as semiconductor masks.
- 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:
+ "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.
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
+ 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.
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
+ A "covered work" means either the unmodified Program or a work based
+ on the Program.
- (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
+ 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.
- (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.
+ 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.
- 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.
+ 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.
- 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.
+ 1. Source Code.
- 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.
+ 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.
- 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.
+ 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.
- 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.
+ 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.
- 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.
+ 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.
- END OF TERMS AND CONDITIONS
+ The Corresponding Source need not include anything that users
+ can regenerate automatically from other parts of the Corresponding
+ Source.
- APPENDIX: How to apply the Apache License to your work.
+ The Corresponding Source for a work in source code form is that
+ same 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.
+ 2. Basic Permissions.
- Copyright [yyyy] [name of copyright owner]
+ 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.
- 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
+ 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.
- http://www.apache.org/licenses/LICENSE-2.0
+ Conveying under any other circumstances is permitted solely under
+ the conditions stated below. Sublicensing is not allowed; section 10
+ makes it unnecessary.
- 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.
+ 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. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+ Program, your modified version must prominently offer all users
+ interacting with it remotely through a computer network (if your version
+ supports such interaction) an opportunity to receive the Corresponding
+ Source of your version by providing access to the Corresponding Source
+ from a network server at no charge, through some standard or customary
+ means of facilitating copying of software. This Corresponding Source
+ shall include the Corresponding Source for any work covered by version 3
+ of the GNU General Public License that is incorporated pursuant to the
+ following paragraph.
+
+ 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 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 work with which it is combined will remain governed by version
+ 3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+ the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+ Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+ network, you should also make sure that it provides a way for users to
+ get its source. For example, if your program is a web application, its
+ interface could display a "Source" link that leads users to an archive
+ of the code. There are many ways you could offer source, and different
+ solutions will be better for different programs; see section 13 for the
+ specific requirements.
+
+ 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 AGPL, see
+ .
diff --git a/Makefile b/Makefile
index b98ec40b..12ebbf20 100644
--- a/Makefile
+++ b/Makefile
@@ -48,6 +48,7 @@ lint:
.PHONY: test
test: | $(GINKGO) $(LINT)
+ go get -t ./...
go vet ./...
go fmt ./...
$(GINKGO) -r --skipPackage=integration_tests,integration
diff --git a/README.md b/README.md
index b940a87d..987235a3 100644
--- a/README.md
+++ b/README.md
@@ -2,23 +2,47 @@
[![Join the chat at https://gitter.im/vulcanizeio/VulcanizeDB](https://badges.gitter.im/vulcanizeio/VulcanizeDB.svg)](https://gitter.im/vulcanizeio/VulcanizeDB?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-[![Build Status](https://travis-ci.com/8thlight/maker-vulcanizedb.svg?token=Wi4xzpyShmtvqatRBWkU&branch=staging)](https://travis-ci.com/8thlight/maker-vulcanizedb)
+[![Build Status](https://travis-ci.com/vulcanize/maker-vulcanizedb.svg?token=MKcE2K7CRvKtdxSSnbap&branch=staging)](https://travis-ci.com/vulcanize/maker-vulcanizedb)
## About
Vulcanize DB is a set of tools that make it easier for developers to write application-specific indexes and caches for dapps built on Ethereum.
## Dependencies
- - Go 1.9+
+ - Go 1.11+
- Postgres 10
- Ethereum Node
- - [Go Ethereum](https://ethereum.github.io/go-ethereum/downloads/) (1.8+)
+ - [Go Ethereum](https://ethereum.github.io/go-ethereum/downloads/) (1.8.21+)
- [Parity 1.8.11+](https://github.com/paritytech/parity/releases)
+## Project Setup
+
+Using Vulcanize for the first time requires several steps be done in order to allow use of the software. The following instructions will offer a guide through the steps of the process:
+
+1. Fetching the project
+2. Installing dependencies
+3. Configuring shell environment
+4. Database setup
+5. Configuring synced Ethereum node integration
+6. Data syncing
+
## Installation
+
+In order to fetch the project codebase for local use or modification, install it to your `GOPATH` via:
+
`go get github.com/vulcanize/vulcanizedb`
`go get gopkg.in/DataDog/dd-trace-go.v1/ddtrace`
+Once fetched, dependencies can be installed via `go get` or (the preferred method) at specific versions via `golang/dep`, the prototype golang pakcage manager. Installation instructions are [here](https://golang.github.io/dep/docs/installation.html).
+
+In order to install packages with `dep`, ensure you are in the project directory now within your `GOPATH` (default location is `~/go/src/github.com/vulcanize/vulcanizedb/`) and run:
+
+`dep ensure`
+
+After `dep` finishes, dependencies should be installed within your `GOPATH` at the versions specified in `Gopkg.toml`.
+
+Lastly, ensure that `GOPATH` is defined in your shell. If necessary, `GOPATH` can be set in `~/.bashrc` or `~/.bash_profile`, depending upon your system. It can be additionally helpful to add `$GOPATH/bin` to your shell's `$PATH`.
+
## Setting up the Database
1. Install Postgres
1. Create a superuser for yourself and make sure `psql --list` works without prompting for a password.
@@ -41,24 +65,24 @@ Vulcanize DB is a set of tools that make it easier for developers to write appli
- To use a local Ethereum node, copy `environments/public.toml.example` to
`environments/public.toml` and update the `ipcPath` and `levelDbPath`.
- `ipcPath` should match the local node's IPC filepath:
- - when using geth:
+ - For Geth:
- The IPC file is called `geth.ipc`.
- The geth IPC file path is printed to the console when you start geth.
- The default location is:
- - Mac: `$HOME/Library/Ethereum`
- - Linux: `$HOME/.ethereum`
+ - Mac: `/Library/Ethereum`
+ - Linux: `/ethereum/geth.ipc`
- - when using parity:
+ - For Parity:
- The IPC file is called `jsonrpc.ipc`.
- The default location is:
- - Mac: `$HOME/Library/Application\ Support/io.parity.ethereum/`
- - Linux: `$HOME/.local/share/io.parity.ethereum/`
+ - Mac: `/Library/Application\ Support/io.parity.ethereum/`
+ - Linux: `/local/share/io.parity.ethereum/`
- `levelDbPath` should match Geth's chaindata directory path.
- The geth LevelDB chaindata path is printed to the console when you start geth.
- The default location is:
- - Mac: `$HOME/Library/Ethereum/geth/chaindata`
- - Linux: `$HOME/.ethereum/geth/chaindata`
+ - Mac: `/Library/Ethereum/geth/chaindata`
+ - Linux: `/ethereum/geth/chaindata`
- `levelDbPath` is irrelevant (and `coldImport` is currently unavailable) if only running parity.
- See `environments/infura.toml` to configure commands to run against infura, if a local node is unavailable.
@@ -75,10 +99,10 @@ This command is useful when you want to maintain a broad cache of what's happeni
Sync VulcanizeDB from the LevelDB underlying a Geth node.
1. Assure node is not running, and that it has synced to the desired block height.
1. Start vulcanize_db
- - `./vulcanizedb coldImport --config --starting-block-number --ending-block-number `
+ - `./vulcanizedb coldImport --config `
1. Optional flags:
- - `--starting-block-number`/`-s`: block number to start syncing from
- - `--ending-block-number`/`-e`: block number to sync to
+ - `--starting-block-number `/`-s `: block number to start syncing from
+ - `--ending-block-number `/`-e `: block number to sync to
- `--all`/`-a`: sync all missing blocks
## Alternatively, sync in "light" mode
@@ -144,3 +168,37 @@ If you have full rinkeby chaindata you can move it to `rinkeby_vulcanizedb_geth_
1. you will need to make sure you have ssh agent running and your ssh key added to it. instructions [here](https://developer.github.com/v3/guides/using-ssh-agent-forwarding/#your-key-must-be-available-to-ssh-agent)
1. `go get -u github.com/pressly/sup/cmd/sup`
1. `sup staging deploy`
+
+## omniWatcher
+These commands require a pre-synced (full or light) vulcanizeDB (see above sections)
+
+To watch all events of a contract using a light synced vDB:
+ - Execute `./vulcanizedb omniWatcher --config --contract-address `
+
+Or if you are using a full synced vDB, change the mode to full:
+ - Execute `./vulcanizedb omniWatcher --mode full --config --contract-address `
+
+To watch contracts on a network other than mainnet, use the network flag:
+ - Execute `./vulcanizedb omniWatcher --config --contract-address --network `
+
+To watch events starting at a certain block use the starting block flag:
+ - Execute `./vulcanizedb omniWatcher --config --contract-address --starting-block-number <#>`
+
+To watch only specified events use the events flag:
+ - Execute `./vulcanizedb omniWatcher --config --contract-address --events --events `
+
+To watch events and poll the specified methods with any addresses and hashes emitted by the watched events utilize the methods flag:
+ - Execute `./vulcanizedb omniWatcher --config --contract-address --methods --methods `
+
+To watch specified events and poll the specified method with any addresses and hashes emitted by the watched events:
+ - Execute `./vulcanizedb omniWatcher --config --contract-address --events --events --methods `
+
+To turn on method piping so that values returned from previous method calls are cached and used as arguments in subsequent method calls:
+ - Execute `./vulcanizedb omniWatcher --config --piping true --contract-address --events --events --methods `
+
+To watch all types of events of the contract but only persist the ones that emit one of the filtered-for argument values:
+ - Execute `./vulcanizedb omniWatcher --config --contract-address --event-args --event-args `
+
+To watch all events of the contract but only poll the specified method with specified argument values (if they are emitted from the watched events):
+ - Execute `./vulcanizedb omniWatcher --config --contract-address --methods --method-args --method-args `
+
diff --git a/cmd/backfillMakerLogs.go b/cmd/backfillMakerLogs.go
index 33b9e919..5bbd65d0 100644
--- a/cmd/backfillMakerLogs.go
+++ b/cmd/backfillMakerLogs.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package cmd
diff --git a/cmd/coldImport.go b/cmd/coldImport.go
index f9045f06..0d8efdbf 100644
--- a/cmd/coldImport.go
+++ b/cmd/coldImport.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package cmd
diff --git a/cmd/continuousLogSync.go b/cmd/continuousLogSync.go
index 19ab7319..59b36bc1 100644
--- a/cmd/continuousLogSync.go
+++ b/cmd/continuousLogSync.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package cmd
diff --git a/cmd/getSignatures.go b/cmd/getSignatures.go
index c5a098ff..a03a2e28 100644
--- a/cmd/getSignatures.go
+++ b/cmd/getSignatures.go
@@ -1,16 +1,18 @@
-// Copyright © 2018 NAME HERE
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package cmd
diff --git a/cmd/lightSync.go b/cmd/lightSync.go
index 630f487f..1b10163b 100644
--- a/cmd/lightSync.go
+++ b/cmd/lightSync.go
@@ -1,21 +1,22 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package cmd
import (
- "os"
"time"
log "github.com/sirupsen/logrus"
@@ -85,7 +86,7 @@ func lightSync() {
if err != nil {
log.Error("ValidateHeaders failed in lightSync: ", err)
}
- window.Log(os.Stdout)
+ log.Info(window.GetString())
case n := <-missingBlocksPopulated:
if n == 0 {
time.Sleep(3 * time.Second)
diff --git a/cmd/omniWatcher.go b/cmd/omniWatcher.go
new file mode 100644
index 00000000..a46549ef
--- /dev/null
+++ b/cmd/omniWatcher.go
@@ -0,0 +1,121 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package cmd
+
+import (
+ "fmt"
+ "log"
+ "time"
+
+ "github.com/spf13/cobra"
+
+ ft "github.com/vulcanize/vulcanizedb/pkg/omni/full/transformer"
+ lt "github.com/vulcanize/vulcanizedb/pkg/omni/light/transformer"
+ st "github.com/vulcanize/vulcanizedb/pkg/omni/shared/transformer"
+ "github.com/vulcanize/vulcanizedb/utils"
+)
+
+// omniWatcherCmd represents the omniWatcher command
+var omniWatcherCmd = &cobra.Command{
+ Use: "omniWatcher",
+ Short: "Watches events at the provided contract address using fully synced vDB",
+ Long: `Uses input contract address and event filters to watch events
+
+Expects an ethereum node to be running
+Expects an archival node synced into vulcanizeDB
+Requires a .toml config file:
+
+ [database]
+ name = "vulcanize_public"
+ hostname = "localhost"
+ port = 5432
+
+ [client]
+ ipcPath = "/Users/user/Library/Ethereum/geth.ipc"
+`,
+ Run: func(cmd *cobra.Command, args []string) {
+ omniWatcher()
+ },
+}
+
+var (
+ network string
+ contractAddress string
+ contractAddresses []string
+ contractEvents []string
+ contractMethods []string
+ eventArgs []string
+ methodArgs []string
+ methodPiping bool
+ mode string
+)
+
+func omniWatcher() {
+ if contractAddress == "" && len(contractAddresses) == 0 {
+ log.Fatal("Contract address required")
+ }
+
+ ticker := time.NewTicker(5 * time.Second)
+ defer ticker.Stop()
+
+ blockChain := getBlockChain()
+ db := utils.LoadPostgres(databaseConfig, blockChain.Node())
+
+ var t st.Transformer
+ switch mode {
+ case "light":
+ t = lt.NewTransformer(network, blockChain, &db)
+ case "full":
+ t = ft.NewTransformer(network, blockChain, &db)
+ default:
+ log.Fatal("Invalid mode")
+ }
+
+ contractAddresses = append(contractAddresses, contractAddress)
+ for _, addr := range contractAddresses {
+ t.SetEvents(addr, contractEvents)
+ t.SetMethods(addr, contractMethods)
+ t.SetEventArgs(addr, eventArgs)
+ t.SetMethodArgs(addr, methodArgs)
+ t.SetPiping(addr, methodPiping)
+ t.SetStartingBlock(addr, startingBlockNumber)
+ }
+
+ err := t.Init()
+ if err != nil {
+ log.Fatal(fmt.Sprintf("Failed to initialized transformer\r\nerr: %v\r\n", err))
+ }
+
+ for range ticker.C {
+ t.Execute()
+ }
+}
+
+func init() {
+ rootCmd.AddCommand(omniWatcherCmd)
+
+ omniWatcherCmd.Flags().StringVarP(&mode, "mode", "o", "light", "'light' or 'full' mode to work with either light synced or fully synced vDB (default is light)")
+ omniWatcherCmd.Flags().StringVarP(&contractAddress, "contract-address", "a", "", "Single address to generate watchers for")
+ omniWatcherCmd.Flags().StringArrayVarP(&contractAddresses, "contract-addresses", "l", []string{}, "list of addresses to use; warning: watcher targets the same events and methods for each address")
+ omniWatcherCmd.Flags().StringArrayVarP(&contractEvents, "events", "e", []string{}, "Subset of events to watch; by default all events are watched")
+ omniWatcherCmd.Flags().StringArrayVarP(&contractMethods, "methods", "m", nil, "Subset of methods to poll; by default no methods are polled")
+ omniWatcherCmd.Flags().StringArrayVarP(&eventArgs, "event-args", "f", []string{}, "Argument values to filter event logs for; will only persist event logs that emit at least one of the value specified")
+ omniWatcherCmd.Flags().StringArrayVarP(&methodArgs, "method-args", "g", []string{}, "Argument values to limit methods to; will only call methods with emitted values that were specified here")
+ omniWatcherCmd.Flags().StringVarP(&network, "network", "n", "", `Network the contract is deployed on; options: "ropsten", "kovan", and "rinkeby"; default is mainnet"`)
+ omniWatcherCmd.Flags().Int64VarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block to begin watching- default is first block the contract exists")
+ omniWatcherCmd.Flags().BoolVarP(&methodPiping, "piping", "p", false, "Turn on method output piping: methods listed first will be polled first and their output used as input to subsequent methods")
+}
diff --git a/cmd/root.go b/cmd/root.go
index ecf2d110..458a5158 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package cmd
@@ -19,12 +21,12 @@ import (
"os"
"time"
+ "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
- "github.com/ethereum/go-ethereum/ethclient"
"github.com/vulcanize/vulcanizedb/pkg/config"
"github.com/vulcanize/vulcanizedb/pkg/geth"
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
diff --git a/cmd/sync.go b/cmd/sync.go
index bbf51a9c..8e1840d3 100644
--- a/cmd/sync.go
+++ b/cmd/sync.go
@@ -1,21 +1,22 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package cmd
import (
- "os"
"time"
log "github.com/sirupsen/logrus"
@@ -85,7 +86,7 @@ func sync() {
select {
case <-ticker.C:
window := validator.ValidateBlocks()
- window.Log(os.Stdout)
+ log.Info(window.GetString())
case <-missingBlocksPopulated:
go backFillAllBlocks(blockChain, blockRepository, missingBlocksPopulated, startingBlockNumber)
}
diff --git a/db/schema.sql b/db/schema.sql
index 4cc89f01..a7871549 100644
--- a/db/schema.sql
+++ b/db/schema.sql
@@ -2677,5 +2677,4 @@ ALTER TABLE ONLY public.logs
--
-- PostgreSQL database dump complete
---
-
+--
\ No newline at end of file
diff --git a/integration_test/block_rewards_test.go b/integration_test/block_rewards_test.go
index 30185d30..f379b870 100644
--- a/integration_test/block_rewards_test.go
+++ b/integration_test/block_rewards_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package integration
import (
diff --git a/integration_test/contract_test.go b/integration_test/contract_test.go
index ad143506..139d46d8 100644
--- a/integration_test/contract_test.go
+++ b/integration_test/contract_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package integration
import (
@@ -8,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/rpc"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/geth"
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
@@ -79,7 +96,10 @@ var _ = Describe("Reading contracts", func() {
contract := testing.SampleContract()
var balance = new(big.Int)
- args := common.HexToHash("0xd26114cd6ee289accf82350c8d8487fedb8a0c07")
+
+ args := make([]interface{}, 1)
+ args[0] = common.HexToHash("0xd26114cd6ee289accf82350c8d8487fedb8a0c07")
+
err = blockChain.FetchContractData(contract.Abi, "0xd26114cd6ee289accf82350c8d8487fedb8a0c07", "balanceOf", args, &balance, 5167471)
Expect(err).NotTo(HaveOccurred())
expected := new(big.Int)
diff --git a/integration_test/geth_blockchain_test.go b/integration_test/geth_blockchain_test.go
index 5435eb14..54719774 100644
--- a/integration_test/geth_blockchain_test.go
+++ b/integration_test/geth_blockchain_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package integration_test
import (
@@ -5,6 +21,7 @@ import (
"github.com/ethereum/go-ethereum/rpc"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/geth"
diff --git a/integration_test/integration_test_suite_test.go b/integration_test/integration_test_suite_test.go
index b9c75608..cc2318de 100644
--- a/integration_test/integration_test_suite_test.go
+++ b/integration_test/integration_test_suite_test.go
@@ -1,10 +1,26 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package integration_test
import (
+ "testing"
+
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
-
- "testing"
)
func TestIntegrationTest(t *testing.T) {
diff --git a/libraries/shared/shared_suite_test.go b/libraries/shared/shared_suite_test.go
index 62a8f3d4..8d079e5d 100644
--- a/libraries/shared/shared_suite_test.go
+++ b/libraries/shared/shared_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package shared_test
import (
diff --git a/libraries/shared/watcher.go b/libraries/shared/watcher.go
index 5e1bfdfd..eddf11c9 100644
--- a/libraries/shared/watcher.go
+++ b/libraries/shared/watcher.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package shared
import (
diff --git a/libraries/shared/watcher_test.go b/libraries/shared/watcher_test.go
index 8312c2b9..94e8fb33 100644
--- a/libraries/shared/watcher_test.go
+++ b/libraries/shared/watcher_test.go
@@ -1,12 +1,30 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package shared_test
import (
"errors"
+
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
"github.com/vulcanize/vulcanizedb/libraries/shared"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
diff --git a/pkg/config/client.go b/pkg/config/client.go
index 48c57c1a..650bf5b1 100644
--- a/pkg/config/client.go
+++ b/pkg/config/client.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package config
type Client struct {
diff --git a/pkg/config/config.go b/pkg/config/config.go
index d53444ea..9b7c9799 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package config
type Config struct {
diff --git a/pkg/config/config_suite_test.go b/pkg/config/config_suite_test.go
index 6508e6da..22df0c6f 100644
--- a/pkg/config/config_suite_test.go
+++ b/pkg/config/config_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package config_test
import (
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index 1059ec45..fe8dc0aa 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package config_test
import (
diff --git a/pkg/config/database.go b/pkg/config/database.go
index 84f139fa..62bdd8bf 100644
--- a/pkg/config/database.go
+++ b/pkg/config/database.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package config
import "fmt"
diff --git a/pkg/core/block.go b/pkg/core/block.go
index a81bdec6..cf3eb5e6 100644
--- a/pkg/core/block.go
+++ b/pkg/core/block.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
type Block struct {
diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go
index ac9fc6a4..829b144b 100644
--- a/pkg/core/blockchain.go
+++ b/pkg/core/blockchain.go
@@ -1,9 +1,26 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
import (
+ "math/big"
+
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core/types"
- "math/big"
)
type BlockChain interface {
@@ -18,5 +35,5 @@ type BlockChain interface {
}
type ContractDataFetcher interface {
- FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error
+ FetchContractData(abiJSON string, address string, method string, methodArgs []interface{}, result interface{}, blockNumber int64) error
}
diff --git a/pkg/core/contract.go b/pkg/core/contract.go
index 8b881e7d..1ca4dffd 100644
--- a/pkg/core/contract.go
+++ b/pkg/core/contract.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
type Contract struct {
diff --git a/pkg/core/eth_client.go b/pkg/core/eth_client.go
index 186f222d..2ec6c6bb 100644
--- a/pkg/core/eth_client.go
+++ b/pkg/core/eth_client.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
import (
diff --git a/pkg/core/header.go b/pkg/core/header.go
index 6d81f122..007e3aad 100644
--- a/pkg/core/header.go
+++ b/pkg/core/header.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
import (
diff --git a/pkg/core/log.go b/pkg/core/log.go
index 984e0432..33ff4146 100644
--- a/pkg/core/log.go
+++ b/pkg/core/log.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
type Log struct {
diff --git a/pkg/core/node_info.go b/pkg/core/node_info.go
index 5477259e..6b84ca36 100644
--- a/pkg/core/node_info.go
+++ b/pkg/core/node_info.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
import (
diff --git a/pkg/core/receipts.go b/pkg/core/receipts.go
index 1d8eaeb0..dad982e6 100644
--- a/pkg/core/receipts.go
+++ b/pkg/core/receipts.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
type Receipt struct {
diff --git a/pkg/core/rpc_client.go b/pkg/core/rpc_client.go
index 51309d93..66b29c00 100644
--- a/pkg/core/rpc_client.go
+++ b/pkg/core/rpc_client.go
@@ -1,7 +1,24 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
import (
"context"
+
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
)
diff --git a/pkg/core/topics.go b/pkg/core/topics.go
index 2f1acb9d..643579b9 100644
--- a/pkg/core/topics.go
+++ b/pkg/core/topics.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
type Topics [4]string
diff --git a/pkg/core/transaction.go b/pkg/core/transaction.go
index e1d45dde..ca3beb9a 100644
--- a/pkg/core/transaction.go
+++ b/pkg/core/transaction.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
type Transaction struct {
diff --git a/pkg/core/watched_event_log.go b/pkg/core/watched_event_log.go
index 04090bcf..fa2a495b 100644
--- a/pkg/core/watched_event_log.go
+++ b/pkg/core/watched_event_log.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package core
type WatchedEvent struct {
diff --git a/pkg/crypto/crypto_suite_test.go b/pkg/crypto/crypto_suite_test.go
index e60462b9..4d08b0b0 100644
--- a/pkg/crypto/crypto_suite_test.go
+++ b/pkg/crypto/crypto_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package crypto_test
import (
diff --git a/pkg/crypto/parser.go b/pkg/crypto/parser.go
index a8448233..91af01a8 100644
--- a/pkg/crypto/parser.go
+++ b/pkg/crypto/parser.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package crypto
import (
diff --git a/pkg/crypto/parser_test.go b/pkg/crypto/parser_test.go
index 77c1478e..711e9d83 100644
--- a/pkg/crypto/parser_test.go
+++ b/pkg/crypto/parser_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package crypto_test
import (
diff --git a/pkg/datastore/ethereum/config.go b/pkg/datastore/ethereum/config.go
index 039089ac..589ae819 100644
--- a/pkg/datastore/ethereum/config.go
+++ b/pkg/datastore/ethereum/config.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package ethereum
type DatabaseType int
diff --git a/pkg/datastore/ethereum/database.go b/pkg/datastore/ethereum/database.go
index c0676c41..2f4bb577 100644
--- a/pkg/datastore/ethereum/database.go
+++ b/pkg/datastore/ethereum/database.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package ethereum
import (
diff --git a/pkg/datastore/ethereum/level/database.go b/pkg/datastore/ethereum/level/database.go
index 81635468..6deb7125 100644
--- a/pkg/datastore/ethereum/level/database.go
+++ b/pkg/datastore/ethereum/level/database.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package level
import (
diff --git a/pkg/datastore/ethereum/level/database_reader.go b/pkg/datastore/ethereum/level/database_reader.go
index 62caae7f..66f49c8d 100644
--- a/pkg/datastore/ethereum/level/database_reader.go
+++ b/pkg/datastore/ethereum/level/database_reader.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package level
import (
diff --git a/pkg/datastore/ethereum/level/database_test.go b/pkg/datastore/ethereum/level/database_test.go
index 4d2018da..5e9de31e 100644
--- a/pkg/datastore/ethereum/level/database_test.go
+++ b/pkg/datastore/ethereum/level/database_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package level_test
import (
diff --git a/pkg/datastore/ethereum/level/level_suite_test.go b/pkg/datastore/ethereum/level/level_suite_test.go
index 20e571bd..26c6cb49 100644
--- a/pkg/datastore/ethereum/level/level_suite_test.go
+++ b/pkg/datastore/ethereum/level/level_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package level_test
import (
diff --git a/pkg/datastore/postgres/postgres.go b/pkg/datastore/postgres/postgres.go
index 0dcdfce8..82a1b2ac 100644
--- a/pkg/datastore/postgres/postgres.go
+++ b/pkg/datastore/postgres/postgres.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package postgres
import (
diff --git a/pkg/datastore/postgres/postgres_suite_test.go b/pkg/datastore/postgres/postgres_suite_test.go
index 34814fba..48c8c677 100644
--- a/pkg/datastore/postgres/postgres_suite_test.go
+++ b/pkg/datastore/postgres/postgres_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package postgres_test
import (
diff --git a/pkg/datastore/postgres/postgres_test.go b/pkg/datastore/postgres/postgres_test.go
index 9ed26252..447665e3 100644
--- a/pkg/datastore/postgres/postgres_test.go
+++ b/pkg/datastore/postgres/postgres_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package postgres_test
import (
diff --git a/pkg/datastore/postgres/repositories/block_repository.go b/pkg/datastore/postgres/repositories/block_repository.go
index 40570e45..92f57144 100644
--- a/pkg/datastore/postgres/repositories/block_repository.go
+++ b/pkg/datastore/postgres/repositories/block_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories
import (
diff --git a/pkg/datastore/postgres/repositories/block_repository_test.go b/pkg/datastore/postgres/repositories/block_repository_test.go
index 4a7bd636..ae391424 100644
--- a/pkg/datastore/postgres/repositories/block_repository_test.go
+++ b/pkg/datastore/postgres/repositories/block_repository_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
diff --git a/pkg/datastore/postgres/repositories/contract_repository.go b/pkg/datastore/postgres/repositories/contract_repository.go
index 1640fd8a..0ff0afdd 100644
--- a/pkg/datastore/postgres/repositories/contract_repository.go
+++ b/pkg/datastore/postgres/repositories/contract_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories
import (
diff --git a/pkg/datastore/postgres/repositories/contract_repository_test.go b/pkg/datastore/postgres/repositories/contract_repository_test.go
index f08ce105..e386cf99 100644
--- a/pkg/datastore/postgres/repositories/contract_repository_test.go
+++ b/pkg/datastore/postgres/repositories/contract_repository_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
diff --git a/pkg/datastore/postgres/repositories/header_repository.go b/pkg/datastore/postgres/repositories/header_repository.go
index bd9635ca..591496e5 100644
--- a/pkg/datastore/postgres/repositories/header_repository.go
+++ b/pkg/datastore/postgres/repositories/header_repository.go
@@ -1,9 +1,27 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories
import (
"database/sql"
"errors"
+
log "github.com/sirupsen/logrus"
+
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
)
diff --git a/pkg/datastore/postgres/repositories/header_repository_test.go b/pkg/datastore/postgres/repositories/header_repository_test.go
index 9aa440df..8bcd1158 100644
--- a/pkg/datastore/postgres/repositories/header_repository_test.go
+++ b/pkg/datastore/postgres/repositories/header_repository_test.go
@@ -1,17 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
"database/sql"
"encoding/json"
+ "math/big"
+
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
"github.com/vulcanize/vulcanizedb/test_config"
- "math/big"
)
var _ = Describe("Block header repository", func() {
@@ -43,7 +61,6 @@ var _ = Describe("Block header repository", func() {
Describe("creating or updating a header", func() {
It("adds a header", func() {
_, err = repo.CreateOrUpdateHeader(header)
-
Expect(err).NotTo(HaveOccurred())
var dbHeader core.Header
err = db.Get(&dbHeader, `SELECT block_number, hash, raw, block_timestamp FROM public.headers WHERE block_number = $1`, header.BlockNumber)
@@ -56,7 +73,6 @@ var _ = Describe("Block header repository", func() {
It("adds node data to header", func() {
_, err = repo.CreateOrUpdateHeader(header)
-
Expect(err).NotTo(HaveOccurred())
var ethNodeId int64
err = db.Get(ðNodeId, `SELECT eth_node_id FROM public.headers WHERE block_number = $1`, header.BlockNumber)
diff --git a/pkg/datastore/postgres/repositories/log_filter_repository.go b/pkg/datastore/postgres/repositories/log_filter_repository.go
index 6b1d3d7c..faad7ca8 100644
--- a/pkg/datastore/postgres/repositories/log_filter_repository.go
+++ b/pkg/datastore/postgres/repositories/log_filter_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories
import (
diff --git a/pkg/datastore/postgres/repositories/log_filter_repository_test.go b/pkg/datastore/postgres/repositories/log_filter_repository_test.go
index d19ffe18..5426868d 100644
--- a/pkg/datastore/postgres/repositories/log_filter_repository_test.go
+++ b/pkg/datastore/postgres/repositories/log_filter_repository_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
diff --git a/pkg/datastore/postgres/repositories/logs_repository.go b/pkg/datastore/postgres/repositories/logs_repository.go
index 45d29b88..4886e15f 100644
--- a/pkg/datastore/postgres/repositories/logs_repository.go
+++ b/pkg/datastore/postgres/repositories/logs_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories
import (
diff --git a/pkg/datastore/postgres/repositories/logs_repository_test.go b/pkg/datastore/postgres/repositories/logs_repository_test.go
index 49621246..1f88cc6c 100644
--- a/pkg/datastore/postgres/repositories/logs_repository_test.go
+++ b/pkg/datastore/postgres/repositories/logs_repository_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
diff --git a/pkg/datastore/postgres/repositories/receipt_repository.go b/pkg/datastore/postgres/repositories/receipt_repository.go
index 997ee58c..9981559c 100644
--- a/pkg/datastore/postgres/repositories/receipt_repository.go
+++ b/pkg/datastore/postgres/repositories/receipt_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories
import (
diff --git a/pkg/datastore/postgres/repositories/receipts_repository_test.go b/pkg/datastore/postgres/repositories/receipts_repository_test.go
index 07917b15..4ba64db4 100644
--- a/pkg/datastore/postgres/repositories/receipts_repository_test.go
+++ b/pkg/datastore/postgres/repositories/receipts_repository_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
diff --git a/pkg/datastore/postgres/repositories/repositories_suite_test.go b/pkg/datastore/postgres/repositories/repositories_suite_test.go
index b222d38c..bf45707e 100644
--- a/pkg/datastore/postgres/repositories/repositories_suite_test.go
+++ b/pkg/datastore/postgres/repositories/repositories_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
diff --git a/pkg/datastore/postgres/repositories/watched_events_repository.go b/pkg/datastore/postgres/repositories/watched_events_repository.go
index d4682d2a..b5931666 100644
--- a/pkg/datastore/postgres/repositories/watched_events_repository.go
+++ b/pkg/datastore/postgres/repositories/watched_events_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories
import (
diff --git a/pkg/datastore/postgres/repositories/watched_events_repository_test.go b/pkg/datastore/postgres/repositories/watched_events_repository_test.go
index 0b224bf2..100e0f00 100644
--- a/pkg/datastore/postgres/repositories/watched_events_repository_test.go
+++ b/pkg/datastore/postgres/repositories/watched_events_repository_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package repositories_test
import (
diff --git a/pkg/datastore/repository.go b/pkg/datastore/repository.go
index 277b8184..32e6c0a8 100644
--- a/pkg/datastore/repository.go
+++ b/pkg/datastore/repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package datastore
import (
diff --git a/pkg/fakes/data.go b/pkg/fakes/data.go
index d8236efc..59a43a2d 100644
--- a/pkg/fakes/data.go
+++ b/pkg/fakes/data.go
@@ -1,13 +1,31 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
"encoding/json"
"errors"
+ "strconv"
+
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
+
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
- "strconv"
)
var (
diff --git a/pkg/fakes/mock_block_repository.go b/pkg/fakes/mock_block_repository.go
index 7c05bfc0..b39a034f 100644
--- a/pkg/fakes/mock_block_repository.go
+++ b/pkg/fakes/mock_block_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
diff --git a/pkg/fakes/mock_blockchain.go b/pkg/fakes/mock_blockchain.go
index 2b7159ee..1cedff56 100644
--- a/pkg/fakes/mock_blockchain.go
+++ b/pkg/fakes/mock_blockchain.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
@@ -15,7 +31,7 @@ type MockBlockChain struct {
fetchContractDataPassedAbi string
fetchContractDataPassedAddress string
fetchContractDataPassedMethod string
- fetchContractDataPassedMethodArg interface{}
+ fetchContractDataPassedMethodArgs []interface{}
fetchContractDataPassedResult interface{}
fetchContractDataPassedBlockNumber int64
getBlockByNumberErr error
@@ -52,14 +68,14 @@ func (chain *MockBlockChain) SetGetEthLogsWithCustomQueryReturnLogs(logs []types
chain.logQueryReturnLogs = logs
}
-func (chain *MockBlockChain) FetchContractData(abiJSON, address, method string, methodArg, result interface{}, blockNumber int64) error {
- chain.fetchContractDataPassedAbi = abiJSON
- chain.fetchContractDataPassedAddress = address
- chain.fetchContractDataPassedMethod = method
- chain.fetchContractDataPassedMethodArg = methodArg
- chain.fetchContractDataPassedResult = result
- chain.fetchContractDataPassedBlockNumber = blockNumber
- return chain.fetchContractDataErr
+func (blockChain *MockBlockChain) FetchContractData(abiJSON string, address string, method string, methodArgs []interface{}, result interface{}, blockNumber int64) error {
+ blockChain.fetchContractDataPassedAbi = abiJSON
+ blockChain.fetchContractDataPassedAddress = address
+ blockChain.fetchContractDataPassedMethod = method
+ blockChain.fetchContractDataPassedMethodArgs = methodArgs
+ blockChain.fetchContractDataPassedResult = result
+ blockChain.fetchContractDataPassedBlockNumber = blockNumber
+ return blockChain.fetchContractDataErr
}
func (chain *MockBlockChain) GetBlockByNumber(blockNumber int64) (core.Block, error) {
@@ -100,12 +116,12 @@ func (chain *MockBlockChain) Node() core.Node {
return chain.node
}
-func (chain *MockBlockChain) AssertFetchContractDataCalledWith(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) {
+func (chain *MockBlockChain) AssertFetchContractDataCalledWith(abiJSON string, address string, method string, methodArgs []interface{}, result interface{}, blockNumber int64) {
Expect(chain.fetchContractDataPassedAbi).To(Equal(abiJSON))
Expect(chain.fetchContractDataPassedAddress).To(Equal(address))
Expect(chain.fetchContractDataPassedMethod).To(Equal(method))
- if methodArg != nil {
- Expect(chain.fetchContractDataPassedMethodArg).To(Equal(methodArg))
+ if methodArgs != nil {
+ Expect(chain.fetchContractDataPassedMethodArgs).To(Equal(methodArgs))
}
Expect(chain.fetchContractDataPassedResult).To(BeAssignableToTypeOf(result))
Expect(chain.fetchContractDataPassedBlockNumber).To(Equal(blockNumber))
diff --git a/pkg/fakes/mock_crypto_parser.go b/pkg/fakes/mock_crypto_parser.go
index 98b21f80..e4de379c 100644
--- a/pkg/fakes/mock_crypto_parser.go
+++ b/pkg/fakes/mock_crypto_parser.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import . "github.com/onsi/gomega"
diff --git a/pkg/fakes/mock_eth_client.go b/pkg/fakes/mock_eth_client.go
index fd040b58..7023e2bd 100644
--- a/pkg/fakes/mock_eth_client.go
+++ b/pkg/fakes/mock_eth_client.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
@@ -8,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/gomega"
+
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
)
diff --git a/pkg/fakes/mock_ethereum_database.go b/pkg/fakes/mock_ethereum_database.go
index a25d2b5c..038d04ba 100644
--- a/pkg/fakes/mock_ethereum_database.go
+++ b/pkg/fakes/mock_ethereum_database.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
diff --git a/pkg/fakes/mock_fs_reader.go b/pkg/fakes/mock_fs_reader.go
index c9a74466..e967a2cd 100644
--- a/pkg/fakes/mock_fs_reader.go
+++ b/pkg/fakes/mock_fs_reader.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import . "github.com/onsi/gomega"
diff --git a/pkg/fakes/mock_header_repository.go b/pkg/fakes/mock_header_repository.go
index 97fad441..1a9bf630 100644
--- a/pkg/fakes/mock_header_repository.go
+++ b/pkg/fakes/mock_header_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
diff --git a/pkg/fakes/mock_level_database_reader.go b/pkg/fakes/mock_level_database_reader.go
index f6d2b7df..261d6be0 100644
--- a/pkg/fakes/mock_level_database_reader.go
+++ b/pkg/fakes/mock_level_database_reader.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
diff --git a/pkg/fakes/mock_receipt_repository.go b/pkg/fakes/mock_receipt_repository.go
index b5d379b3..5663eeed 100644
--- a/pkg/fakes/mock_receipt_repository.go
+++ b/pkg/fakes/mock_receipt_repository.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
diff --git a/pkg/fakes/mock_rpc_client.go b/pkg/fakes/mock_rpc_client.go
index 8f25ef87..fe615555 100644
--- a/pkg/fakes/mock_rpc_client.go
+++ b/pkg/fakes/mock_rpc_client.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
@@ -77,7 +93,6 @@ func (client *MockRpcClient) CallContext(ctx context.Context, result interface{}
if client.callContextErr != nil {
return client.callContextErr
}
-
case "parity_versionInfo":
if p, ok := result.(*core.ParityNodeInfo); ok {
*p = core.ParityNodeInfo{
diff --git a/pkg/fakes/mock_transaction_converter.go b/pkg/fakes/mock_transaction_converter.go
index 8595dec0..b36c390e 100644
--- a/pkg/fakes/mock_transaction_converter.go
+++ b/pkg/fakes/mock_transaction_converter.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fakes
import (
diff --git a/pkg/filters/filter_query.go b/pkg/filters/filter_query.go
index 60956ec8..26e3f428 100644
--- a/pkg/filters/filter_query.go
+++ b/pkg/filters/filter_query.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package filters
import (
diff --git a/pkg/filters/filter_test.go b/pkg/filters/filter_test.go
index 474f0311..ea475f8c 100644
--- a/pkg/filters/filter_test.go
+++ b/pkg/filters/filter_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package filters_test
import (
diff --git a/pkg/filters/query_builder_suite_test.go b/pkg/filters/query_builder_suite_test.go
index 42029812..7f49afb6 100644
--- a/pkg/filters/query_builder_suite_test.go
+++ b/pkg/filters/query_builder_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package filters_test
import (
diff --git a/pkg/fs/reader.go b/pkg/fs/reader.go
index 4029b8a7..fe9df6ac 100644
--- a/pkg/fs/reader.go
+++ b/pkg/fs/reader.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package fs
import "io/ioutil"
diff --git a/pkg/geth/abi.go b/pkg/geth/abi.go
index 5211dd98..d6943597 100644
--- a/pkg/geth/abi.go
+++ b/pkg/geth/abi.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package geth
import (
diff --git a/pkg/geth/abi_test.go b/pkg/geth/abi_test.go
index 8843564e..3e5a78dc 100644
--- a/pkg/geth/abi_test.go
+++ b/pkg/geth/abi_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package geth_test
import (
diff --git a/pkg/geth/blockchain.go b/pkg/geth/blockchain.go
index 7b9c49dd..347aa7c4 100644
--- a/pkg/geth/blockchain.go
+++ b/pkg/geth/blockchain.go
@@ -1,18 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package geth
import (
"errors"
"math/big"
+ "strconv"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
+ "golang.org/x/net/context"
+
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
- "golang.org/x/net/context"
- "strconv"
)
var ErrEmptyHeader = errors.New("empty header returned over RPC")
diff --git a/pkg/geth/blockchain_test.go b/pkg/geth/blockchain_test.go
index 5f81ef78..217e5326 100644
--- a/pkg/geth/blockchain_test.go
+++ b/pkg/geth/blockchain_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package geth_test
import (
@@ -5,12 +21,12 @@ import (
"math/big"
"github.com/ethereum/go-ethereum"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
vulcCore "github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/geth"
diff --git a/pkg/geth/client/eth_client.go b/pkg/geth/client/eth_client.go
index 21b7cd3d..c4af6009 100644
--- a/pkg/geth/client/eth_client.go
+++ b/pkg/geth/client/eth_client.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package client
import (
diff --git a/pkg/geth/client/rpc_client.go b/pkg/geth/client/rpc_client.go
index 76c84494..43f9892e 100644
--- a/pkg/geth/client/rpc_client.go
+++ b/pkg/geth/client/rpc_client.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package client
import (
diff --git a/pkg/geth/cold_import/cold_import_suite_test.go b/pkg/geth/cold_import/cold_import_suite_test.go
index 8c524782..22f9632c 100644
--- a/pkg/geth/cold_import/cold_import_suite_test.go
+++ b/pkg/geth/cold_import/cold_import_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package cold_import_test
import (
diff --git a/pkg/geth/cold_import/importer.go b/pkg/geth/cold_import/importer.go
index fbf4f90f..9ebeb0dc 100644
--- a/pkg/geth/cold_import/importer.go
+++ b/pkg/geth/cold_import/importer.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package cold_import
import (
diff --git a/pkg/geth/cold_import/importer_test.go b/pkg/geth/cold_import/importer_test.go
index 5f9bf58c..3e50b110 100644
--- a/pkg/geth/cold_import/importer_test.go
+++ b/pkg/geth/cold_import/importer_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package cold_import_test
import (
diff --git a/pkg/geth/cold_import/node_builder.go b/pkg/geth/cold_import/node_builder.go
index f3f79899..4e39bf69 100644
--- a/pkg/geth/cold_import/node_builder.go
+++ b/pkg/geth/cold_import/node_builder.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package cold_import
import (
diff --git a/pkg/geth/cold_import/node_builder_test.go b/pkg/geth/cold_import/node_builder_test.go
index ec19a009..83300078 100644
--- a/pkg/geth/cold_import/node_builder_test.go
+++ b/pkg/geth/cold_import/node_builder_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package cold_import_test
import (
diff --git a/pkg/geth/contract.go b/pkg/geth/contract.go
index 8e47f02f..4c49f422 100644
--- a/pkg/geth/contract.go
+++ b/pkg/geth/contract.go
@@ -1,9 +1,24 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package geth
import (
- "errors"
-
"context"
+ "errors"
"math/big"
"github.com/ethereum/go-ethereum"
@@ -14,14 +29,14 @@ var (
ErrInvalidStateAttribute = errors.New("invalid state attribute")
)
-func (blockChain *BlockChain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
+func (blockChain *BlockChain) FetchContractData(abiJSON string, address string, method string, methodArgs []interface{}, result interface{}, blockNumber int64) error {
parsed, err := ParseAbi(abiJSON)
if err != nil {
return err
}
var input []byte
- if methodArg != nil {
- input, err = parsed.Pack(method, methodArg)
+ if methodArgs != nil {
+ input, err = parsed.Pack(method, methodArgs...)
} else {
input, err = parsed.Pack(method)
}
diff --git a/pkg/geth/converters/cold_db/transaction_converter.go b/pkg/geth/converters/cold_db/transaction_converter.go
index 044e6226..3b095754 100644
--- a/pkg/geth/converters/cold_db/transaction_converter.go
+++ b/pkg/geth/converters/cold_db/transaction_converter.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package cold_db
import (
diff --git a/pkg/geth/converters/common/block_converter.go b/pkg/geth/converters/common/block_converter.go
index 6e13f474..8976a164 100644
--- a/pkg/geth/converters/common/block_converter.go
+++ b/pkg/geth/converters/common/block_converter.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common
import (
diff --git a/pkg/geth/converters/common/block_converter_test.go b/pkg/geth/converters/common/block_converter_test.go
index bf4fe0da..0df05be4 100644
--- a/pkg/geth/converters/common/block_converter_test.go
+++ b/pkg/geth/converters/common/block_converter_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common_test
import (
diff --git a/pkg/geth/converters/common/block_rewards.go b/pkg/geth/converters/common/block_rewards.go
index f37a938a..51c967fc 100644
--- a/pkg/geth/converters/common/block_rewards.go
+++ b/pkg/geth/converters/common/block_rewards.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common
import (
diff --git a/pkg/geth/converters/common/common_suite_test.go b/pkg/geth/converters/common/common_suite_test.go
index 690b5549..3d8de4d8 100644
--- a/pkg/geth/converters/common/common_suite_test.go
+++ b/pkg/geth/converters/common/common_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common_test
import (
diff --git a/pkg/geth/converters/common/header_converter.go b/pkg/geth/converters/common/header_converter.go
index a6cd2eaf..c160e427 100644
--- a/pkg/geth/converters/common/header_converter.go
+++ b/pkg/geth/converters/common/header_converter.go
@@ -1,7 +1,24 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common
import (
"encoding/json"
+
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/core"
)
diff --git a/pkg/geth/converters/common/header_converter_test.go b/pkg/geth/converters/common/header_converter_test.go
index f25b02eb..7eb12d83 100644
--- a/pkg/geth/converters/common/header_converter_test.go
+++ b/pkg/geth/converters/common/header_converter_test.go
@@ -1,8 +1,23 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common_test
import (
"encoding/json"
- "github.com/vulcanize/vulcanizedb/pkg/fakes"
"math/big"
"github.com/ethereum/go-ethereum/common"
@@ -10,6 +25,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ "github.com/vulcanize/vulcanizedb/pkg/fakes"
common2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
)
diff --git a/pkg/geth/converters/common/log_converter.go b/pkg/geth/converters/common/log_converter.go
index 47c0d0e9..11dce787 100644
--- a/pkg/geth/converters/common/log_converter.go
+++ b/pkg/geth/converters/common/log_converter.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common
import (
diff --git a/pkg/geth/converters/common/log_converter_test.go b/pkg/geth/converters/common/log_converter_test.go
index b6e37385..d382aa25 100644
--- a/pkg/geth/converters/common/log_converter_test.go
+++ b/pkg/geth/converters/common/log_converter_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common_test
import (
diff --git a/pkg/geth/converters/common/receipt_converter.go b/pkg/geth/converters/common/receipt_converter.go
index aff58fa1..5d558948 100644
--- a/pkg/geth/converters/common/receipt_converter.go
+++ b/pkg/geth/converters/common/receipt_converter.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common
import (
diff --git a/pkg/geth/converters/common/receipt_converter_test.go b/pkg/geth/converters/common/receipt_converter_test.go
index 08a7c5eb..b43b6152 100644
--- a/pkg/geth/converters/common/receipt_converter_test.go
+++ b/pkg/geth/converters/common/receipt_converter_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common_test
import (
diff --git a/pkg/geth/converters/common/transaction_converter.go b/pkg/geth/converters/common/transaction_converter.go
index 6bc1a8fc..320dc975 100644
--- a/pkg/geth/converters/common/transaction_converter.go
+++ b/pkg/geth/converters/common/transaction_converter.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package common
import (
diff --git a/pkg/geth/converters/rpc/transaction_converter.go b/pkg/geth/converters/rpc/transaction_converter.go
index c1dda565..d741f908 100644
--- a/pkg/geth/converters/rpc/transaction_converter.go
+++ b/pkg/geth/converters/rpc/transaction_converter.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package rpc
import (
diff --git a/pkg/geth/geth_suite_test.go b/pkg/geth/geth_suite_test.go
index 2d293f6c..c4078ffc 100644
--- a/pkg/geth/geth_suite_test.go
+++ b/pkg/geth/geth_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package geth_test
import (
diff --git a/pkg/geth/node/node.go b/pkg/geth/node/node.go
index ae70ada0..7c276097 100644
--- a/pkg/geth/node/node.go
+++ b/pkg/geth/node/node.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package node
import (
diff --git a/pkg/geth/node/node_suite_test.go b/pkg/geth/node/node_suite_test.go
index 102033dc..27139341 100644
--- a/pkg/geth/node/node_suite_test.go
+++ b/pkg/geth/node/node_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package node_test
import (
diff --git a/pkg/geth/node/node_test.go b/pkg/geth/node/node_test.go
index c63214ca..58ad5ca9 100644
--- a/pkg/geth/node/node_test.go
+++ b/pkg/geth/node/node_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package node_test
import (
diff --git a/pkg/geth/testing/helpers.go b/pkg/geth/testing/helpers.go
index ae289962..1a612703 100644
--- a/pkg/geth/testing/helpers.go
+++ b/pkg/geth/testing/helpers.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package testing
import (
diff --git a/pkg/history/block_validator.go b/pkg/history/block_validator.go
index 4f98cbca..6f7791a2 100644
--- a/pkg/history/block_validator.go
+++ b/pkg/history/block_validator.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history
import (
diff --git a/pkg/history/block_validator_test.go b/pkg/history/block_validator_test.go
index e05e6501..3509e20e 100644
--- a/pkg/history/block_validator_test.go
+++ b/pkg/history/block_validator_test.go
@@ -1,12 +1,29 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history_test
import (
+ "math/big"
+
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/history"
- "math/big"
)
var _ = Describe("Blocks validator", func() {
diff --git a/pkg/history/header_validator.go b/pkg/history/header_validator.go
index 5d10eab0..c475473d 100644
--- a/pkg/history/header_validator.go
+++ b/pkg/history/header_validator.go
@@ -1,7 +1,24 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history
import (
log "github.com/sirupsen/logrus"
+
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore"
)
diff --git a/pkg/history/header_validator_test.go b/pkg/history/header_validator_test.go
index 937c04ef..674c4ab6 100644
--- a/pkg/history/header_validator_test.go
+++ b/pkg/history/header_validator_test.go
@@ -1,12 +1,30 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history_test
import (
"errors"
+ "math/big"
+
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/history"
- "math/big"
)
var _ = Describe("Header validator", func() {
diff --git a/pkg/history/history_suite_test.go b/pkg/history/history_suite_test.go
index 96068ec7..3e99e488 100644
--- a/pkg/history/history_suite_test.go
+++ b/pkg/history/history_suite_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history_test
import (
diff --git a/pkg/history/populate_blocks.go b/pkg/history/populate_blocks.go
index 884e5521..72f38840 100644
--- a/pkg/history/populate_blocks.go
+++ b/pkg/history/populate_blocks.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history
import (
diff --git a/pkg/history/populate_blocks_test.go b/pkg/history/populate_blocks_test.go
index e80687a3..5ff67a13 100644
--- a/pkg/history/populate_blocks_test.go
+++ b/pkg/history/populate_blocks_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history_test
import (
diff --git a/pkg/history/populate_headers.go b/pkg/history/populate_headers.go
index 1339e9e0..499dcb86 100644
--- a/pkg/history/populate_headers.go
+++ b/pkg/history/populate_headers.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history
import (
@@ -44,6 +60,5 @@ func RetrieveAndUpdateHeaders(chain core.BlockChain, headerRepository datastore.
return 0, err
}
}
-
return len(blockNumbers), nil
}
diff --git a/pkg/history/populate_headers_test.go b/pkg/history/populate_headers_test.go
index b2bd569b..6b06fbb4 100644
--- a/pkg/history/populate_headers_test.go
+++ b/pkg/history/populate_headers_test.go
@@ -1,3 +1,19 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history_test
import (
diff --git a/pkg/history/validation_window.go b/pkg/history/validation_window.go
index e10253c3..f6ba1a18 100644
--- a/pkg/history/validation_window.go
+++ b/pkg/history/validation_window.go
@@ -1,8 +1,24 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history
import (
+ "fmt"
"github.com/vulcanize/vulcanizedb/pkg/core"
- "io"
"text/template"
)
@@ -36,6 +52,7 @@ func MakeRange(min, max int64) []int64 {
return a
}
-func (window ValidationWindow) Log(out io.Writer) {
- ParsedWindowTemplate.Execute(out, window)
+func (window ValidationWindow) GetString() string {
+ return fmt.Sprintf("Validating Blocks |%v|-- Validation Window --|%v}|",
+ window.LowerBound, window.UpperBound)
}
diff --git a/pkg/history/validation_window_test.go b/pkg/history/validation_window_test.go
index 354af33e..50683be4 100644
--- a/pkg/history/validation_window_test.go
+++ b/pkg/history/validation_window_test.go
@@ -1,8 +1,22 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package history_test
import (
- "bytes"
-
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -34,15 +48,4 @@ var _ = Describe("Validation window", func() {
Expect(numberOfBlocksCreated).To(Equal(expected))
})
-
- It("logs window message", func() {
- expectedMessage := &bytes.Buffer{}
- window := history.ValidationWindow{LowerBound: 5, UpperBound: 7}
- history.ParsedWindowTemplate.Execute(expectedMessage, window)
- actualMessage := &bytes.Buffer{}
-
- window.Log(actualMessage)
-
- Expect(actualMessage).To(Equal(expectedMessage))
- })
})
diff --git a/pkg/omni/full/converter/converter.go b/pkg/omni/full/converter/converter.go
new file mode 100644
index 00000000..dd5b9725
--- /dev/null
+++ b/pkg/omni/full/converter/converter.go
@@ -0,0 +1,122 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package converter
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "strconv"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+// Converter is used to convert watched event logs to
+// custom logs containing event input name => value maps
+type Converter interface {
+ Convert(watchedEvent core.WatchedEvent, event types.Event) (*types.Log, error)
+ Update(info *contract.Contract)
+}
+
+type converter struct {
+ ContractInfo *contract.Contract
+}
+
+func NewConverter(info *contract.Contract) *converter {
+ return &converter{
+ ContractInfo: info,
+ }
+}
+
+func (c *converter) Update(info *contract.Contract) {
+ c.ContractInfo = info
+}
+
+// Convert the given watched event log into a types.Log for the given event
+func (c *converter) Convert(watchedEvent core.WatchedEvent, event types.Event) (*types.Log, error) {
+ contract := bind.NewBoundContract(common.HexToAddress(c.ContractInfo.Address), c.ContractInfo.ParsedAbi, nil, nil, nil)
+ values := make(map[string]interface{})
+ log := helpers.ConvertToLog(watchedEvent)
+ err := contract.UnpackLogIntoMap(values, event.Name, log)
+ if err != nil {
+ return nil, err
+ }
+
+ strValues := make(map[string]string, len(values))
+ seenAddrs := make([]interface{}, 0, len(values))
+ seenHashes := make([]interface{}, 0, len(values))
+ for fieldName, input := range values {
+ // Postgres cannot handle custom types, resolve to strings
+ switch input.(type) {
+ case *big.Int:
+ b := input.(*big.Int)
+ strValues[fieldName] = b.String()
+ case common.Address:
+ a := input.(common.Address)
+ strValues[fieldName] = a.String()
+ seenAddrs = append(seenAddrs, a)
+ case common.Hash:
+ h := input.(common.Hash)
+ strValues[fieldName] = h.String()
+ seenHashes = append(seenHashes, h)
+ case string:
+ strValues[fieldName] = input.(string)
+ case bool:
+ strValues[fieldName] = strconv.FormatBool(input.(bool))
+ case []byte:
+ b := input.([]byte)
+ strValues[fieldName] = hexutil.Encode(b)
+ if len(b) == 32 { // collect byte arrays of size 32 as hashes
+ seenHashes = append(seenHashes, common.HexToHash(strValues[fieldName]))
+ }
+ case byte:
+ b := input.(byte)
+ strValues[fieldName] = string(b)
+ default:
+ return nil, errors.New(fmt.Sprintf("error: unhandled abi type %T", input))
+ }
+ }
+
+ // Only hold onto logs that pass our address filter, if any
+ if c.ContractInfo.PassesEventFilter(strValues) {
+ eventLog := &types.Log{
+ Id: watchedEvent.LogID,
+ Values: strValues,
+ Block: watchedEvent.BlockNumber,
+ Tx: watchedEvent.TxHash,
+ }
+
+ // Cache emitted values if their caching is turned on
+ if c.ContractInfo.EmittedAddrs != nil {
+ c.ContractInfo.AddEmittedAddr(seenAddrs...)
+ }
+ if c.ContractInfo.EmittedHashes != nil {
+ c.ContractInfo.AddEmittedHash(seenHashes...)
+ }
+
+ return eventLog, nil
+ }
+
+ return nil, nil
+}
diff --git a/pkg/omni/full/converter/converter_suite_test.go b/pkg/omni/full/converter/converter_suite_test.go
new file mode 100644
index 00000000..93fd8aef
--- /dev/null
+++ b/pkg/omni/full/converter/converter_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package converter_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestConverter(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Full Converter Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/full/converter/converter_test.go b/pkg/omni/full/converter/converter_test.go
new file mode 100644
index 00000000..e35780b8
--- /dev/null
+++ b/pkg/omni/full/converter/converter_test.go
@@ -0,0 +1,109 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package converter_test
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/omni/full/converter"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+)
+
+var _ = Describe("Converter", func() {
+ var con *contract.Contract
+ var wantedEvents = []string{"Transfer"}
+ var err error
+
+ BeforeEach(func() {
+ con = test_helpers.SetupTusdContract(wantedEvents, []string{"balanceOf"})
+ })
+
+ Describe("Update", func() {
+ It("Updates contract con held by the converter", func() {
+ c := converter.NewConverter(con)
+ Expect(c.ContractInfo).To(Equal(con))
+
+ con := test_helpers.SetupTusdContract([]string{}, []string{})
+ c.Update(con)
+ Expect(c.ContractInfo).To(Equal(con))
+ })
+ })
+
+ Describe("Convert", func() {
+ It("Converts a watched event log to mapping of event input names to values", func() {
+ _, ok := con.Events["Approval"]
+ Expect(ok).To(Equal(false))
+
+ event, ok := con.Events["Transfer"]
+ Expect(ok).To(Equal(true))
+ err = con.GenerateFilters()
+ Expect(err).ToNot(HaveOccurred())
+
+ c := converter.NewConverter(con)
+ log, err := c.Convert(mocks.MockTranferEvent, event)
+ Expect(err).ToNot(HaveOccurred())
+
+ from := common.HexToAddress("0x000000000000000000000000000000000000000000000000000000000000af21")
+ to := common.HexToAddress("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391")
+ value := helpers.BigFromString("1097077688018008265106216665536940668749033598146")
+
+ v := log.Values["value"]
+
+ Expect(log.Values["to"]).To(Equal(to.String()))
+ Expect(log.Values["from"]).To(Equal(from.String()))
+ Expect(v).To(Equal(value.String()))
+ })
+
+ It("Keeps track of addresses it sees to grow a token holder address list for the contract", func() {
+ event, ok := con.Events["Transfer"]
+ Expect(ok).To(Equal(true))
+
+ c := converter.NewConverter(con)
+ _, err := c.Convert(mocks.MockTranferEvent, event)
+ Expect(err).ToNot(HaveOccurred())
+
+ b, ok := con.EmittedAddrs[common.HexToAddress("0x000000000000000000000000000000000000Af21")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = con.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ _, ok = con.EmittedAddrs[common.HexToAddress("0x")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = con.EmittedAddrs[""]
+ Expect(ok).To(Equal(false))
+
+ _, ok = con.EmittedAddrs[common.HexToAddress("0x09THISE21a5IS5cFAKE1D82fAND43bCE06MADEUP")]
+ Expect(ok).To(Equal(false))
+ })
+
+ It("Fails with an empty contract", func() {
+ event := con.Events["Transfer"]
+ c := converter.NewConverter(&contract.Contract{})
+ _, err = c.Convert(mocks.MockTranferEvent, event)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+})
diff --git a/pkg/omni/full/retriever/block_retriever.go b/pkg/omni/full/retriever/block_retriever.go
new file mode 100644
index 00000000..f4c3ac5d
--- /dev/null
+++ b/pkg/omni/full/retriever/block_retriever.go
@@ -0,0 +1,87 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever
+
+import (
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+)
+
+// Block retriever is used to retrieve the first block for a given contract and the most recent block
+// It requires a vDB synced database with blocks, transactions, receipts, and logs
+type BlockRetriever interface {
+ RetrieveFirstBlock(contractAddr string) (int64, error)
+ RetrieveMostRecentBlock() (int64, error)
+}
+
+type blockRetriever struct {
+ db *postgres.DB
+}
+
+func NewBlockRetriever(db *postgres.DB) (r *blockRetriever) {
+ return &blockRetriever{
+ db: db,
+ }
+}
+
+// Try both methods of finding the first block, with the receipt method taking precedence
+func (r *blockRetriever) RetrieveFirstBlock(contractAddr string) (int64, error) {
+ i, err := r.retrieveFirstBlockFromReceipts(contractAddr)
+ if err != nil {
+ i, err = r.retrieveFirstBlockFromLogs(contractAddr)
+ }
+
+ return i, err
+}
+
+// For some contracts the contract creation transaction receipt doesn't have the contract address so this doesn't work (e.g. Sai)
+func (r *blockRetriever) retrieveFirstBlockFromReceipts(contractAddr string) (int64, error) {
+ var firstBlock int
+ err := r.db.Get(
+ &firstBlock,
+ `SELECT number FROM blocks
+ WHERE id = (SELECT block_id FROM receipts
+ WHERE lower(contract_address) = $1
+ ORDER BY block_id ASC
+ LIMIT 1)`,
+ contractAddr,
+ )
+
+ return int64(firstBlock), err
+}
+
+// In which case this servers as a heuristic to find the first block by finding the first contract event log
+func (r *blockRetriever) retrieveFirstBlockFromLogs(contractAddr string) (int64, error) {
+ var firstBlock int
+ err := r.db.Get(
+ &firstBlock,
+ "SELECT block_number FROM logs WHERE lower(address) = $1 ORDER BY block_number ASC LIMIT 1",
+ contractAddr,
+ )
+
+ return int64(firstBlock), err
+}
+
+// Method to retrieve the most recent block in vDB
+func (r *blockRetriever) RetrieveMostRecentBlock() (int64, error) {
+ var lastBlock int64
+ err := r.db.Get(
+ &lastBlock,
+ "SELECT number FROM blocks ORDER BY number DESC LIMIT 1",
+ )
+
+ return lastBlock, err
+}
diff --git a/pkg/omni/full/retriever/block_retriever_test.go b/pkg/omni/full/retriever/block_retriever_test.go
new file mode 100644
index 00000000..caa1a1ed
--- /dev/null
+++ b/pkg/omni/full/retriever/block_retriever_test.go
@@ -0,0 +1,218 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever_test
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "strings"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/full/retriever"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+)
+
+var _ = Describe("Block Retriever", func() {
+ var db *postgres.DB
+ var r retriever.BlockRetriever
+ var blockRepository repositories.BlockRepository
+
+ // Contains no contract address
+ var block1 = core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ert",
+ Number: 1,
+ Transactions: []core.Transaction{},
+ }
+
+ BeforeEach(func() {
+ db, _ = test_helpers.SetupDBandBC()
+ blockRepository = *repositories.NewBlockRepository(db)
+ r = retriever.NewBlockRetriever(db)
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("RetrieveFirstBlock", func() {
+ It("Retrieves block number where contract first appears in receipt, if available", func() {
+
+ // Contains the address in the receipt
+ block2 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ert",
+ Number: 2,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ ContractAddress: constants.TusdContractAddress,
+ Logs: []core.Log{},
+ },
+ }},
+ }
+
+ // Contains address in logs
+ block3 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad456yui",
+ Number: 3,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad234hfs",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad234hfs",
+ ContractAddress: constants.TusdContractAddress,
+ Logs: []core.Log{{
+ BlockNumber: 3,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad234hfs",
+ Address: constants.TusdContractAddress,
+ Topics: core.Topics{
+ constants.TransferEvent.Signature(),
+ "0x000000000000000000000000000000000000000000000000000000000000af21",
+ "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ "",
+ },
+ Index: 1,
+ Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
+ }},
+ },
+ }},
+ }
+
+ blockRepository.CreateOrUpdateBlock(block1)
+ blockRepository.CreateOrUpdateBlock(block2)
+ blockRepository.CreateOrUpdateBlock(block3)
+
+ i, err := r.RetrieveFirstBlock(strings.ToLower(constants.TusdContractAddress))
+ Expect(err).NotTo(HaveOccurred())
+ Expect(i).To(Equal(int64(2)))
+ })
+
+ It("Retrieves block number where contract first appears in event logs if it cannot find the address in a receipt", func() {
+
+ block2 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ert",
+ Number: 2,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ ContractAddress: "",
+ Logs: []core.Log{{
+ BlockNumber: 2,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ Address: constants.DaiContractAddress,
+ Topics: core.Topics{
+ constants.TransferEvent.Signature(),
+ "0x000000000000000000000000000000000000000000000000000000000000af21",
+ "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ "",
+ },
+ Index: 1,
+ Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
+ }},
+ },
+ }},
+ }
+
+ block3 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad456yui",
+ Number: 3,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad234hfs",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad234hfs",
+ ContractAddress: "",
+ Logs: []core.Log{{
+ BlockNumber: 3,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad234hfs",
+ Address: constants.DaiContractAddress,
+ Topics: core.Topics{
+ constants.TransferEvent.Signature(),
+ "0x000000000000000000000000000000000000000000000000000000000000af21",
+ "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ "",
+ },
+ Index: 1,
+ Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
+ }},
+ },
+ }},
+ }
+
+ blockRepository.CreateOrUpdateBlock(block1)
+ blockRepository.CreateOrUpdateBlock(block2)
+ blockRepository.CreateOrUpdateBlock(block3)
+
+ i, err := r.RetrieveFirstBlock(constants.DaiContractAddress)
+ Expect(err).NotTo(HaveOccurred())
+ Expect(i).To(Equal(int64(2)))
+ })
+
+ It("Fails if the contract address cannot be found in any blocks", func() {
+ block2 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ert",
+ Number: 2,
+ Transactions: []core.Transaction{},
+ }
+
+ block3 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad456yui",
+ Number: 3,
+ Transactions: []core.Transaction{},
+ }
+
+ blockRepository.CreateOrUpdateBlock(block1)
+ blockRepository.CreateOrUpdateBlock(block2)
+ blockRepository.CreateOrUpdateBlock(block3)
+
+ _, err := r.RetrieveFirstBlock(constants.DaiContractAddress)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("RetrieveMostRecentBlock", func() {
+ It("Retrieves the latest block", func() {
+ block2 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ert",
+ Number: 2,
+ Transactions: []core.Transaction{},
+ }
+
+ block3 := core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad456yui",
+ Number: 3,
+ Transactions: []core.Transaction{},
+ }
+
+ blockRepository.CreateOrUpdateBlock(block1)
+ blockRepository.CreateOrUpdateBlock(block2)
+ blockRepository.CreateOrUpdateBlock(block3)
+
+ i, err := r.RetrieveMostRecentBlock()
+ Expect(err).ToNot(HaveOccurred())
+ Expect(i).To(Equal(int64(3)))
+ })
+
+ It("Fails if it cannot retrieve the latest block", func() {
+ i, err := r.RetrieveMostRecentBlock()
+ Expect(err).To(HaveOccurred())
+ Expect(i).To(Equal(int64(0)))
+ })
+ })
+})
diff --git a/pkg/omni/full/retriever/retriever_suite_test.go b/pkg/omni/full/retriever/retriever_suite_test.go
new file mode 100644
index 00000000..948f5e8e
--- /dev/null
+++ b/pkg/omni/full/retriever/retriever_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestRetriever(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Full Block Number Retriever Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/full/transformer/transformer.go b/pkg/omni/full/transformer/transformer.go
new file mode 100644
index 00000000..5c8a4337
--- /dev/null
+++ b/pkg/omni/full/transformer/transformer.go
@@ -0,0 +1,271 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer
+
+import (
+ "errors"
+ "strings"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/full/converter"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/full/retriever"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/parser"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/poller"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+// Requires a fully synced vDB and a running eth node (or infura)
+type transformer struct {
+ // Database interfaces
+ datastore.FilterRepository // Log filters repo; accepts filters generated by Contract.GenerateFilters()
+ datastore.WatchedEventRepository // Watched event log views, created by the log filters
+ repository.EventRepository // Holds transformed watched event log data
+
+ // Pre-processing interfaces
+ parser.Parser // Parses events and methods out of contract abi fetched using contract address
+ retriever.BlockRetriever // Retrieves first block for contract and current block height
+
+ // Processing interfaces
+ converter.Converter // Converts watched event logs into custom log
+ poller.Poller // Polls methods using contract's token holder addresses and persists them using method datastore
+
+ // Ethereum network name; default "" is mainnet
+ Network string
+
+ // Store contract info as mapping to contract address
+ Contracts map[string]*contract.Contract
+
+ // Targeted subset of events/methods
+ // Stored as map sof contract address to events/method names of interest
+ WatchedEvents map[string][]string // Default/empty event list means all are watched
+ WantedMethods map[string][]string // Default/empty method list means none are polled
+
+ // Starting block for contracts
+ ContractStart map[string]int64
+
+ // Lists of addresses to filter event or method data
+ // before persisting; if empty no filter is applied
+ EventArgs map[string][]string
+ MethodArgs map[string][]string
+
+ // Whether or not to create a list of emitted address or hashes for the contract in postgres
+ CreateAddrList map[string]bool
+ CreateHashList map[string]bool
+
+ // Method piping on/off for a contract
+ Piping map[string]bool
+}
+
+// Transformer takes in config for blockchain, database, and network id
+func NewTransformer(network string, BC core.BlockChain, DB *postgres.DB) *transformer {
+ return &transformer{
+ Poller: poller.NewPoller(BC, DB, types.FullSync),
+ Parser: parser.NewParser(network),
+ BlockRetriever: retriever.NewBlockRetriever(DB),
+ Converter: converter.NewConverter(&contract.Contract{}),
+ Contracts: map[string]*contract.Contract{},
+ WatchedEventRepository: repositories.WatchedEventRepository{DB: DB},
+ FilterRepository: repositories.FilterRepository{DB: DB},
+ EventRepository: repository.NewEventRepository(DB, types.FullSync),
+ WatchedEvents: map[string][]string{},
+ WantedMethods: map[string][]string{},
+ ContractStart: map[string]int64{},
+ EventArgs: map[string][]string{},
+ MethodArgs: map[string][]string{},
+ CreateAddrList: map[string]bool{},
+ CreateHashList: map[string]bool{},
+ Piping: map[string]bool{},
+ }
+}
+
+// Use after creating and setting transformer
+// Loops over all of the addr => filter sets
+// Uses parser to pull event info from abi
+// Use this info to generate event filters
+func (t *transformer) Init() error {
+ for contractAddr, subset := range t.WatchedEvents {
+ // Get Abi
+ err := t.Parser.Parse(contractAddr)
+ if err != nil {
+ return err
+ }
+
+ // Get first block and most recent block number in the header repo
+ firstBlock, err := t.BlockRetriever.RetrieveFirstBlock(contractAddr)
+ if err != nil {
+ return err
+ }
+ lastBlock, err := t.BlockRetriever.RetrieveMostRecentBlock()
+ if err != nil {
+ return err
+ }
+
+ // Set to specified range if it falls within the bounds
+ if firstBlock < t.ContractStart[contractAddr] {
+ firstBlock = t.ContractStart[contractAddr]
+ }
+
+ // Get contract name if it has one
+ var name = new(string)
+ t.FetchContractData(t.Abi(), contractAddr, "name", nil, &name, lastBlock)
+
+ // Remove any potential accidental duplicate inputs in arg filter values
+ eventArgs := map[string]bool{}
+ for _, arg := range t.EventArgs[contractAddr] {
+ eventArgs[arg] = true
+ }
+ methodArgs := map[string]bool{}
+ for _, arg := range t.MethodArgs[contractAddr] {
+ methodArgs[arg] = true
+ }
+
+ // Aggregate info into contract object
+ info := contract.Contract{
+ Name: *name,
+ Network: t.Network,
+ Address: contractAddr,
+ Abi: t.Parser.Abi(),
+ ParsedAbi: t.Parser.ParsedAbi(),
+ StartingBlock: firstBlock,
+ LastBlock: lastBlock,
+ Events: t.Parser.GetEvents(subset),
+ Methods: t.Parser.GetSelectMethods(t.WantedMethods[contractAddr]),
+ FilterArgs: eventArgs,
+ MethodArgs: methodArgs,
+ CreateAddrList: t.CreateAddrList[contractAddr],
+ CreateHashList: t.CreateHashList[contractAddr],
+ Piping: t.Piping[contractAddr],
+ }.Init()
+
+ // Use info to create filters
+ err = info.GenerateFilters()
+ if err != nil {
+ return err
+ }
+
+ // Iterate over filters and push them to the repo using filter repository interface
+ for _, filter := range info.Filters {
+ err = t.CreateFilter(filter)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Store contract info for further processing
+ t.Contracts[contractAddr] = info
+ }
+
+ return nil
+}
+
+// Iterates through stored, initialized contract objects
+// Iterates through contract's event filters, grabbing watched event logs
+// Uses converter to convert logs into custom log type
+// Persists converted logs into custuom postgres tables
+// Calls selected methods, using token holder address generated during event log conversion
+func (tr transformer) Execute() error {
+ if len(tr.Contracts) == 0 {
+ return errors.New("error: transformer has no initialized contracts to work with")
+ }
+ // Iterate through all internal contracts
+ for _, con := range tr.Contracts {
+ // Update converter with current contract
+ tr.Update(con)
+
+ // Iterate through contract filters and get watched event logs
+ for eventSig, filter := range con.Filters {
+ watchedEvents, err := tr.GetWatchedEvents(filter.Name)
+ if err != nil {
+ return err
+ }
+
+ // Iterate over watched event logs
+ for _, we := range watchedEvents {
+ // Convert them to our custom log type
+ cstm, err := tr.Converter.Convert(*we, con.Events[eventSig])
+ if err != nil {
+ return err
+ }
+ if cstm == nil {
+ continue
+ }
+
+ // If log is not empty, immediately persist in repo
+ // Run this in seperate goroutine?
+ err = tr.PersistLogs([]types.Log{*cstm}, con.Events[eventSig], con.Address, con.Name)
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ // After persisting all watched event logs
+ // poller polls select contract methods
+ // and persists the results into custom pg tables
+ // Run this in seperate goroutine?
+ if err := tr.PollContract(*con); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Used to set which contract addresses and which of their events to watch
+func (tr *transformer) SetEvents(contractAddr string, filterSet []string) {
+ tr.WatchedEvents[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set subset of account addresses to watch events for
+func (tr *transformer) SetEventArgs(contractAddr string, filterSet []string) {
+ tr.EventArgs[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set which contract addresses and which of their methods to call
+func (tr *transformer) SetMethods(contractAddr string, filterSet []string) {
+ tr.WantedMethods[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set subset of account addresses to poll methods on
+func (tr *transformer) SetMethodArgs(contractAddr string, filterSet []string) {
+ tr.MethodArgs[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set the block range to watch for a given address
+func (tr *transformer) SetStartingBlock(contractAddr string, start int64) {
+ tr.ContractStart[strings.ToLower(contractAddr)] = start
+}
+
+// Used to set whether or not to persist an account address list
+func (tr *transformer) SetCreateAddrList(contractAddr string, on bool) {
+ tr.CreateAddrList[strings.ToLower(contractAddr)] = on
+}
+
+// Used to set whether or not to persist an hash list
+func (tr *transformer) SetCreateHashList(contractAddr string, on bool) {
+ tr.CreateHashList[strings.ToLower(contractAddr)] = on
+}
+
+// Used to turn method piping on for a contract
+func (tr *transformer) SetPiping(contractAddr string, on bool) {
+ tr.Piping[strings.ToLower(contractAddr)] = on
+}
diff --git a/pkg/omni/full/transformer/transformer_suite_test.go b/pkg/omni/full/transformer/transformer_suite_test.go
new file mode 100644
index 00000000..1f362f2b
--- /dev/null
+++ b/pkg/omni/full/transformer/transformer_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestTransformer(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Full Transformer Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/full/transformer/transformer_test.go b/pkg/omni/full/transformer/transformer_test.go
new file mode 100644
index 00000000..9d68143c
--- /dev/null
+++ b/pkg/omni/full/transformer/transformer_test.go
@@ -0,0 +1,369 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer_test
+
+import (
+ "fmt"
+ "math/rand"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/full/transformer"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+)
+
+var _ = Describe("Transformer", func() {
+ var db *postgres.DB
+ var err error
+ var blockChain core.BlockChain
+ var blockRepository repositories.BlockRepository
+ var ensAddr = strings.ToLower(constants.EnsContractAddress)
+ var tusdAddr = strings.ToLower(constants.TusdContractAddress)
+ rand.Seed(time.Now().UnixNano())
+
+ BeforeEach(func() {
+ db, blockChain = test_helpers.SetupDBandBC()
+ blockRepository = *repositories.NewBlockRepository(db)
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("SetEvents", func() {
+ It("Sets which events to watch from the given contract address", func() {
+ watchedEvents := []string{"Transfer", "Mint"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, watchedEvents)
+ Expect(t.WatchedEvents[tusdAddr]).To(Equal(watchedEvents))
+ })
+ })
+
+ Describe("SetEventAddrs", func() {
+ It("Sets which account addresses to watch events for", func() {
+ eventAddrs := []string{"test1", "test2"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEventArgs(constants.TusdContractAddress, eventAddrs)
+ Expect(t.EventArgs[tusdAddr]).To(Equal(eventAddrs))
+ })
+ })
+
+ Describe("SetMethods", func() {
+ It("Sets which methods to poll at the given contract address", func() {
+ watchedMethods := []string{"balanceOf", "totalSupply"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetMethods(constants.TusdContractAddress, watchedMethods)
+ Expect(t.WantedMethods[tusdAddr]).To(Equal(watchedMethods))
+ })
+ })
+
+ Describe("SetMethodAddrs", func() {
+ It("Sets which account addresses to poll methods against", func() {
+ methodAddrs := []string{"test1", "test2"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetMethodArgs(constants.TusdContractAddress, methodAddrs)
+ Expect(t.MethodArgs[tusdAddr]).To(Equal(methodAddrs))
+ })
+ })
+
+ Describe("SetStartingBlock", func() {
+ It("Sets the block range that the contract should be watched within", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetStartingBlock(constants.TusdContractAddress, 11)
+ Expect(t.ContractStart[tusdAddr]).To(Equal(int64(11)))
+ })
+ })
+
+ Describe("SetCreateAddrList", func() {
+ It("Sets the block range that the contract should be watched within", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetCreateAddrList(constants.TusdContractAddress, true)
+ Expect(t.CreateAddrList[tusdAddr]).To(Equal(true))
+ })
+ })
+
+ Describe("SetCreateHashList", func() {
+ It("Sets the block range that the contract should be watched within", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetCreateHashList(constants.TusdContractAddress, true)
+ Expect(t.CreateHashList[tusdAddr]).To(Equal(true))
+ })
+ })
+
+ Describe("Init", func() {
+ It("Initializes transformer's contract objects", func() {
+ blockRepository.CreateOrUpdateBlock(mocks.TransferBlock1)
+ blockRepository.CreateOrUpdateBlock(mocks.TransferBlock2)
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ c, ok := t.Contracts[tusdAddr]
+ Expect(ok).To(Equal(true))
+
+ Expect(c.StartingBlock).To(Equal(int64(6194633)))
+ Expect(c.LastBlock).To(Equal(int64(6194634)))
+ Expect(c.Abi).To(Equal(constants.TusdAbiString))
+ Expect(c.Name).To(Equal("TrueUSD"))
+ Expect(c.Address).To(Equal(tusdAddr))
+ })
+
+ It("Fails to initialize if first and most recent blocks cannot be fetched from vDB", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ err = t.Init()
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("Does nothing if watched events are unset", func() {
+ blockRepository.CreateOrUpdateBlock(mocks.TransferBlock1)
+ blockRepository.CreateOrUpdateBlock(mocks.TransferBlock2)
+ t := transformer.NewTransformer("", blockChain, db)
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ _, ok := t.Contracts[tusdAddr]
+ Expect(ok).To(Equal(false))
+ })
+ })
+
+ Describe("Execute", func() {
+ BeforeEach(func() {
+ blockRepository.CreateOrUpdateBlock(mocks.TransferBlock1)
+ blockRepository.CreateOrUpdateBlock(mocks.TransferBlock2)
+ })
+
+ It("Transforms watched contract data into custom repositories", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, nil)
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ log := test_helpers.TransferLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.transfer_event WHERE block = 6194634", tusdAddr)).StructScan(&log)
+
+ // We don't know vulcID, so compare individual fields instead of complete structures
+ Expect(log.Tx).To(Equal("0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654eee"))
+ Expect(log.Block).To(Equal(int64(6194634)))
+ Expect(log.From).To(Equal("0x000000000000000000000000000000000000Af21"))
+ Expect(log.To).To(Equal("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"))
+ Expect(log.Value).To(Equal("1097077688018008265106216665536940668749033598146"))
+ })
+
+ It("Keeps track of contract-related addresses while transforming event data if they need to be used for later method polling", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ c, ok := t.Contracts[tusdAddr]
+ Expect(ok).To(Equal(true))
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ b, ok := c.EmittedAddrs[common.HexToAddress("0x000000000000000000000000000000000000Af21")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = c.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843b1234567890")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = c.EmittedAddrs[""]
+ Expect(ok).To(Equal(false))
+
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x09THISE21a5IS5cFAKE1D82fAND43bCE06MADEUP")]
+ Expect(ok).To(Equal(false))
+ })
+
+ It("Polls given methods using generated token holder address", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ res := test_helpers.BalanceOf{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0x000000000000000000000000000000000000Af21' AND block = '6194634'", tusdAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Balance).To(Equal("0"))
+ Expect(res.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0x09BbBBE21a5975cAc061D82f7b843bCE061BA391' AND block = '6194634'", tusdAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Balance).To(Equal("0"))
+ Expect(res.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0xfE9e8709d3215310075d67E3ed32A380CCf451C8' AND block = '6194634'", tusdAddr)).StructScan(&res)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("Fails if initialization has not been done", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, nil)
+
+ err = t.Execute()
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("Execute- against ENS registry contract", func() {
+ BeforeEach(func() {
+ blockRepository.CreateOrUpdateBlock(mocks.NewOwnerBlock1)
+ blockRepository.CreateOrUpdateBlock(mocks.NewOwnerBlock2)
+ })
+
+ It("Transforms watched contract data into custom repositories", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, nil)
+
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ log := test_helpers.NewOwnerLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.newowner_event", ensAddr)).StructScan(&log)
+
+ // We don't know vulcID, so compare individual fields instead of complete structures
+ Expect(log.Tx).To(Equal("0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654bbb"))
+ Expect(log.Block).To(Equal(int64(6194635)))
+ Expect(log.Node).To(Equal("0x0000000000000000000000000000000000000000000000000000c02aaa39b223"))
+ Expect(log.Label).To(Equal("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391"))
+ Expect(log.Owner).To(Equal("0x000000000000000000000000000000000000Af21"))
+ })
+
+ It("Keeps track of contract-related hashes while transforming event data if they need to be used for later method polling", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ c, ok := t.Contracts[ensAddr]
+ Expect(ok).To(Equal(true))
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(c.EmittedHashes)).To(Equal(3))
+
+ b, ok := c.EmittedHashes[common.HexToHash("0x0000000000000000000000000000000000000000000000000000c02aaa39b223")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = c.EmittedHashes[common.HexToHash("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ // Doesn't keep track of address since it wouldn't be used in calling the 'owner' method
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x000000000000000000000000000000000000Af21")]
+ Expect(ok).To(Equal(false))
+ })
+
+ It("Polls given methods using generated token holder address", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ res := test_helpers.Owner{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x0000000000000000000000000000000000000000000000000000c02aaa39b223' AND block = '6194636'", ensAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000"))
+ Expect(res.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391' AND block = '6194636'", ensAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000"))
+ Expect(res.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHIS288IS625bFAKE' AND block = '6194636'", ensAddr)).StructScan(&res)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("It does not perist events if they do not pass the emitted arg filter", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, nil)
+ t.SetEventArgs(constants.EnsContractAddress, []string{"fake_filter_value"})
+
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ log := test_helpers.LightNewOwnerLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.newowner_event", ensAddr)).StructScan(&log)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("If a method arg filter is applied, only those arguments are used in polling", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ t.SetMethodArgs(constants.EnsContractAddress, []string{"0x0000000000000000000000000000000000000000000000000000c02aaa39b223"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ res := test_helpers.Owner{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x0000000000000000000000000000000000000000000000000000c02aaa39b223' AND block = '6194636'", ensAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000"))
+ Expect(res.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391' AND block = '6194636'", ensAddr)).StructScan(&res)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+})
diff --git a/pkg/omni/light/converter/converter.go b/pkg/omni/light/converter/converter.go
new file mode 100644
index 00000000..3deba288
--- /dev/null
+++ b/pkg/omni/light/converter/converter.go
@@ -0,0 +1,213 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package converter
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "math/big"
+ "strconv"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ gethTypes "github.com/ethereum/go-ethereum/core/types"
+
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+type Converter interface {
+ Convert(logs []gethTypes.Log, event types.Event, headerID int64) ([]types.Log, error)
+ ConvertBatch(logs []gethTypes.Log, events map[string]types.Event, headerID int64) (map[string][]types.Log, error)
+ Update(info *contract.Contract)
+}
+
+type converter struct {
+ ContractInfo *contract.Contract
+}
+
+func NewConverter(info *contract.Contract) *converter {
+ return &converter{
+ ContractInfo: info,
+ }
+}
+
+func (c *converter) Update(info *contract.Contract) {
+ c.ContractInfo = info
+}
+
+// Convert the given watched event log into a types.Log for the given event
+func (c *converter) Convert(logs []gethTypes.Log, event types.Event, headerID int64) ([]types.Log, error) {
+ contract := bind.NewBoundContract(common.HexToAddress(c.ContractInfo.Address), c.ContractInfo.ParsedAbi, nil, nil, nil)
+ returnLogs := make([]types.Log, 0, len(logs))
+ for _, log := range logs {
+ values := make(map[string]interface{})
+ for _, field := range event.Fields {
+ var i interface{}
+ values[field.Name] = i
+ }
+
+ err := contract.UnpackLogIntoMap(values, event.Name, log)
+ if err != nil {
+ return nil, err
+ }
+
+ strValues := make(map[string]string, len(values))
+ seenAddrs := make([]interface{}, 0, len(values))
+ seenHashes := make([]interface{}, 0, len(values))
+ for fieldName, input := range values {
+ // Postgres cannot handle custom types, resolve everything to strings
+ switch input.(type) {
+ case *big.Int:
+ b := input.(*big.Int)
+ strValues[fieldName] = b.String()
+ case common.Address:
+ a := input.(common.Address)
+ strValues[fieldName] = a.String()
+ seenAddrs = append(seenAddrs, a)
+ case common.Hash:
+ h := input.(common.Hash)
+ strValues[fieldName] = h.String()
+ seenHashes = append(seenHashes, h)
+ case string:
+ strValues[fieldName] = input.(string)
+ case bool:
+ strValues[fieldName] = strconv.FormatBool(input.(bool))
+ case []byte:
+ b := input.([]byte)
+ strValues[fieldName] = hexutil.Encode(b)
+ if len(b) == 32 {
+ seenHashes = append(seenHashes, common.HexToHash(strValues[fieldName]))
+ }
+ case byte:
+ b := input.(byte)
+ strValues[fieldName] = string(b)
+ default:
+ return nil, errors.New(fmt.Sprintf("error: unhandled abi type %T", input))
+ }
+ }
+
+ // Only hold onto logs that pass our address filter, if any
+ if c.ContractInfo.PassesEventFilter(strValues) {
+ raw, err := json.Marshal(log)
+ if err != nil {
+ return nil, err
+ }
+
+ returnLogs = append(returnLogs, types.Log{
+ LogIndex: log.Index,
+ Values: strValues,
+ Raw: raw,
+ TransactionIndex: log.TxIndex,
+ Id: headerID,
+ })
+
+ // Cache emitted values if their caching is turned on
+ if c.ContractInfo.EmittedAddrs != nil {
+ c.ContractInfo.AddEmittedAddr(seenAddrs...)
+ }
+ if c.ContractInfo.EmittedHashes != nil {
+ c.ContractInfo.AddEmittedHash(seenHashes...)
+ }
+ }
+ }
+
+ return returnLogs, nil
+}
+
+// Convert the given watched event logs into types.Logs; returns a map of event names to a slice of their converted logs
+func (c *converter) ConvertBatch(logs []gethTypes.Log, events map[string]types.Event, headerID int64) (map[string][]types.Log, error) {
+ contract := bind.NewBoundContract(common.HexToAddress(c.ContractInfo.Address), c.ContractInfo.ParsedAbi, nil, nil, nil)
+ eventsToLogs := make(map[string][]types.Log)
+ for _, event := range events {
+ eventsToLogs[event.Name] = make([]types.Log, 0, len(logs))
+ // Iterate through all event logs
+ for _, log := range logs {
+ // If the log is of this event type, process it as such
+ if event.Sig() == log.Topics[0] {
+ values := make(map[string]interface{})
+ err := contract.UnpackLogIntoMap(values, event.Name, log)
+ if err != nil {
+ return nil, err
+ }
+ // Postgres cannot handle custom types, so we will resolve everything to strings
+ strValues := make(map[string]string, len(values))
+ // Keep track of addresses and hashes emitted from events
+ seenAddrs := make([]interface{}, 0, len(values))
+ seenHashes := make([]interface{}, 0, len(values))
+ for fieldName, input := range values {
+ switch input.(type) {
+ case *big.Int:
+ b := input.(*big.Int)
+ strValues[fieldName] = b.String()
+ case common.Address:
+ a := input.(common.Address)
+ strValues[fieldName] = a.String()
+ seenAddrs = append(seenAddrs, a)
+ case common.Hash:
+ h := input.(common.Hash)
+ strValues[fieldName] = h.String()
+ seenHashes = append(seenHashes, h)
+ case string:
+ strValues[fieldName] = input.(string)
+ case bool:
+ strValues[fieldName] = strconv.FormatBool(input.(bool))
+ case []byte:
+ b := input.([]byte)
+ strValues[fieldName] = hexutil.Encode(b)
+ if len(b) == 32 { // collect byte arrays of size 32 as hashes
+ seenHashes = append(seenHashes, common.BytesToHash(b))
+ }
+ case byte:
+ b := input.(byte)
+ strValues[fieldName] = string(b)
+ default:
+ return nil, errors.New(fmt.Sprintf("error: unhandled abi type %T", input))
+ }
+ }
+
+ // Only hold onto logs that pass our argument filter, if any
+ if c.ContractInfo.PassesEventFilter(strValues) {
+ raw, err := json.Marshal(log)
+ if err != nil {
+ return nil, err
+ }
+
+ eventsToLogs[event.Name] = append(eventsToLogs[event.Name], types.Log{
+ LogIndex: log.Index,
+ Values: strValues,
+ Raw: raw,
+ TransactionIndex: log.TxIndex,
+ Id: headerID,
+ })
+
+ // Cache emitted values that pass the argument filter if their caching is turned on
+ if c.ContractInfo.EmittedAddrs != nil {
+ c.ContractInfo.AddEmittedAddr(seenAddrs...)
+ }
+ if c.ContractInfo.EmittedHashes != nil {
+ c.ContractInfo.AddEmittedHash(seenHashes...)
+ }
+ }
+ }
+ }
+ }
+
+ return eventsToLogs, nil
+}
diff --git a/pkg/omni/light/converter/converter_suite_test.go b/pkg/omni/light/converter/converter_suite_test.go
new file mode 100644
index 00000000..d69367df
--- /dev/null
+++ b/pkg/omni/light/converter/converter_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package converter_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestConverter(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Light Converter Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/light/converter/converter_test.go b/pkg/omni/light/converter/converter_test.go
new file mode 100644
index 00000000..374bb699
--- /dev/null
+++ b/pkg/omni/light/converter/converter_test.go
@@ -0,0 +1,151 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package converter_test
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/converter"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+)
+
+var _ = Describe("Converter", func() {
+ var con *contract.Contract
+ var tusdWantedEvents = []string{"Transfer", "Mint"}
+ var ensWantedEvents = []string{"NewOwner"}
+ var err error
+
+ Describe("Update", func() {
+ It("Updates contract info held by the converter", func() {
+ con = test_helpers.SetupTusdContract(tusdWantedEvents, []string{})
+ c := converter.NewConverter(con)
+ Expect(c.ContractInfo).To(Equal(con))
+
+ info := test_helpers.SetupTusdContract([]string{}, []string{})
+ c.Update(info)
+ Expect(c.ContractInfo).To(Equal(info))
+ })
+ })
+
+ Describe("Convert", func() {
+ It("Converts a watched event log to mapping of event input names to values", func() {
+ con = test_helpers.SetupTusdContract(tusdWantedEvents, []string{})
+ _, ok := con.Events["Approval"]
+ Expect(ok).To(Equal(false))
+
+ event, ok := con.Events["Transfer"]
+ Expect(ok).To(Equal(true))
+
+ c := converter.NewConverter(con)
+ logs, err := c.Convert([]types.Log{mocks.MockTransferLog1, mocks.MockTransferLog2}, event, 232)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(logs)).To(Equal(2))
+
+ sender1 := common.HexToAddress("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391")
+ sender2 := common.HexToAddress("0x000000000000000000000000000000000000000000000000000000000000af21")
+ value := helpers.BigFromString("1097077688018008265106216665536940668749033598146")
+
+ Expect(logs[0].Values["to"]).To(Equal(sender1.String()))
+ Expect(logs[0].Values["from"]).To(Equal(sender2.String()))
+ Expect(logs[0].Values["value"]).To(Equal(value.String()))
+ Expect(logs[0].Id).To(Equal(int64(232)))
+ Expect(logs[1].Values["to"]).To(Equal(sender2.String()))
+ Expect(logs[1].Values["from"]).To(Equal(sender1.String()))
+ Expect(logs[1].Values["value"]).To(Equal(value.String()))
+ Expect(logs[1].Id).To(Equal(int64(232)))
+ })
+
+ It("Keeps track of addresses it sees if they will be used for method polling", func() {
+ con = test_helpers.SetupTusdContract(tusdWantedEvents, []string{"balanceOf"})
+ event, ok := con.Events["Transfer"]
+ Expect(ok).To(Equal(true))
+
+ c := converter.NewConverter(con)
+ _, err := c.Convert([]types.Log{mocks.MockTransferLog1, mocks.MockTransferLog2}, event, 232)
+ Expect(err).ToNot(HaveOccurred())
+
+ b, ok := con.EmittedAddrs[common.HexToAddress("0x000000000000000000000000000000000000Af21")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = con.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ _, ok = con.EmittedAddrs[common.HexToAddress("0x")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = con.EmittedAddrs[""]
+ Expect(ok).To(Equal(false))
+
+ _, ok = con.EmittedAddrs[common.HexToAddress("0x09THISE21a5IS5cFAKE1D82fAND43bCE06MADEUP")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = con.EmittedHashes[common.HexToHash("0x000000000000000000000000c02aaa39b223helloa0e5c4f27ead9083c752553")]
+ Expect(ok).To(Equal(false))
+ })
+
+ It("Keeps track of hashes it sees if they will be used for method polling", func() {
+ con = test_helpers.SetupENSContract(ensWantedEvents, []string{"owner"})
+ event, ok := con.Events["NewOwner"]
+ Expect(ok).To(Equal(true))
+
+ c := converter.NewConverter(con)
+ _, err := c.Convert([]types.Log{mocks.MockNewOwnerLog1, mocks.MockNewOwnerLog2}, event, 232)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(con.EmittedHashes)).To(Equal(3))
+
+ b, ok := con.EmittedHashes[common.HexToHash("0x000000000000000000000000c02aaa39b223helloa0e5c4f27ead9083c752553")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = con.EmittedHashes[common.HexToHash("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = con.EmittedHashes[common.HexToHash("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba400")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ _, ok = con.EmittedHashes[common.HexToHash("0x9dd48thiscc444isc242510c0made03upa5975cac061dhashb843bce061ba400")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = con.EmittedHashes[common.HexToAddress("0x")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = con.EmittedHashes[""]
+ Expect(ok).To(Equal(false))
+
+ // Does not keep track of emitted addresses if the methods provided will not use them
+ _, ok = con.EmittedAddrs[common.HexToAddress("0x000000000000000000000000000000000000Af21")]
+ Expect(ok).To(Equal(false))
+ })
+
+ It("Fails with an empty contract", func() {
+ event := con.Events["Transfer"]
+ c := converter.NewConverter(&contract.Contract{})
+ _, err = c.Convert([]types.Log{mocks.MockTransferLog1}, event, 232)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+})
diff --git a/pkg/omni/light/fetcher/fetcher.go b/pkg/omni/light/fetcher/fetcher.go
new file mode 100644
index 00000000..77162f0e
--- /dev/null
+++ b/pkg/omni/light/fetcher/fetcher.go
@@ -0,0 +1,69 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package fetcher
+
+import (
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+)
+
+type Fetcher interface {
+ FetchLogs(contractAddresses []string, topics []common.Hash, missingHeader core.Header) ([]types.Log, error)
+}
+
+type fetcher struct {
+ blockChain core.BlockChain
+}
+
+func NewFetcher(blockchain core.BlockChain) *fetcher {
+ return &fetcher{
+ blockChain: blockchain,
+ }
+}
+
+// Checks all topic0s, on all addresses, fetching matching logs for the given header
+func (fetcher *fetcher) FetchLogs(contractAddresses []string, topic0s []common.Hash, header core.Header) ([]types.Log, error) {
+ addresses := hexStringsToAddresses(contractAddresses)
+ blockHash := common.HexToHash(header.Hash)
+ query := ethereum.FilterQuery{
+ BlockHash: &blockHash,
+ Addresses: addresses,
+ // Search for _any_ of the topics in topic0 position; see docs on `FilterQuery`
+ Topics: [][]common.Hash{topic0s},
+ }
+
+ logs, err := fetcher.blockChain.GetEthLogsWithCustomQuery(query)
+ if err != nil {
+ // TODO review aggregate fetching error handling
+ return []types.Log{}, err
+ }
+
+ return logs, nil
+}
+
+func hexStringsToAddresses(hexStrings []string) []common.Address {
+ var addresses []common.Address
+ for _, hexString := range hexStrings {
+ address := common.HexToAddress(hexString)
+ addresses = append(addresses, address)
+ }
+
+ return addresses
+}
diff --git a/pkg/omni/light/fetcher/fetcher_suite_test.go b/pkg/omni/light/fetcher/fetcher_suite_test.go
new file mode 100644
index 00000000..3b60a906
--- /dev/null
+++ b/pkg/omni/light/fetcher/fetcher_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package fetcher_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestFetcher(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Fetcher Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/light/fetcher/fetcher_test.go b/pkg/omni/light/fetcher/fetcher_test.go
new file mode 100644
index 00000000..8dca9ca8
--- /dev/null
+++ b/pkg/omni/light/fetcher/fetcher_test.go
@@ -0,0 +1,66 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package fetcher_test
+
+import (
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/common"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/fakes"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/fetcher"
+)
+
+var _ = Describe("Fetcher", func() {
+ Describe("FetchLogs", func() {
+ It("fetches logs based on the given query", func() {
+ blockChain := fakes.NewMockBlockChain()
+ fetcher := fetcher.NewFetcher(blockChain)
+ header := fakes.FakeHeader
+
+ addresses := []string{"0xfakeAddress", "0xanotherFakeAddress"}
+ topicZeros := [][]common.Hash{{common.BytesToHash([]byte{1, 2, 3, 4, 5})}}
+
+ _, err := fetcher.FetchLogs(addresses, []common.Hash{common.BytesToHash([]byte{1, 2, 3, 4, 5})}, header)
+
+ address1 := common.HexToAddress("0xfakeAddress")
+ address2 := common.HexToAddress("0xanotherFakeAddress")
+ Expect(err).NotTo(HaveOccurred())
+
+ blockHash := common.HexToHash(header.Hash)
+ expectedQuery := ethereum.FilterQuery{
+ BlockHash: &blockHash,
+ Addresses: []common.Address{address1, address2},
+ Topics: topicZeros,
+ }
+ blockChain.AssertGetEthLogsWithCustomQueryCalledWith(expectedQuery)
+ })
+
+ It("returns an error if fetching the logs fails", func() {
+ blockChain := fakes.NewMockBlockChain()
+ blockChain.SetGetEthLogsWithCustomQueryErr(fakes.FakeError)
+ fetcher := fetcher.NewFetcher(blockChain)
+
+ _, err := fetcher.FetchLogs([]string{}, []common.Hash{}, core.Header{})
+
+ Expect(err).To(HaveOccurred())
+ Expect(err).To(MatchError(fakes.FakeError))
+ })
+ })
+})
diff --git a/pkg/omni/light/repository/header_repository.go b/pkg/omni/light/repository/header_repository.go
new file mode 100644
index 00000000..c26b3e60
--- /dev/null
+++ b/pkg/omni/light/repository/header_repository.go
@@ -0,0 +1,259 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository
+
+import (
+ "database/sql"
+ "fmt"
+
+ "github.com/hashicorp/golang-lru"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+)
+
+const columnCacheSize = 1000
+
+type HeaderRepository interface {
+ AddCheckColumn(id string) error
+ AddCheckColumns(ids []string) error
+ MarkHeaderChecked(headerID int64, eventID string) error
+ MarkHeaderCheckedForAll(headerID int64, ids []string) error
+ MarkHeadersCheckedForAll(headers []core.Header, ids []string) error
+ MissingHeaders(startingBlockNumber int64, endingBlockNumber int64, eventID string) ([]core.Header, error)
+ MissingMethodsCheckedEventsIntersection(startingBlockNumber, endingBlockNumber int64, methodIds, eventIds []string) ([]core.Header, error)
+ MissingHeadersForAll(startingBlockNumber, endingBlockNumber int64, ids []string) ([]core.Header, error)
+ CheckCache(key string) (interface{}, bool)
+}
+
+type headerRepository struct {
+ db *postgres.DB
+ columns *lru.Cache // Cache created columns to minimize db connections
+}
+
+func NewHeaderRepository(db *postgres.DB) *headerRepository {
+ ccs, _ := lru.New(columnCacheSize)
+ return &headerRepository{
+ db: db,
+ columns: ccs,
+ }
+}
+
+func (r *headerRepository) AddCheckColumn(id string) error {
+ // Check cache to see if column already exists before querying pg
+ _, ok := r.columns.Get(id)
+ if ok {
+ return nil
+ }
+
+ pgStr := "ALTER TABLE public.checked_headers ADD COLUMN IF NOT EXISTS "
+ pgStr = pgStr + id + " BOOLEAN NOT NULL DEFAULT FALSE"
+ _, err := r.db.Exec(pgStr)
+ if err != nil {
+ return err
+ }
+
+ // Add column name to cache
+ r.columns.Add(id, true)
+
+ return nil
+}
+
+func (r *headerRepository) AddCheckColumns(ids []string) error {
+ var err error
+ baseQuery := "ALTER TABLE public.checked_headers"
+ input := make([]string, 0, len(ids))
+ for _, id := range ids {
+ _, ok := r.columns.Get(id)
+ if !ok {
+ baseQuery += " ADD COLUMN IF NOT EXISTS " + id + " BOOLEAN NOT NULL DEFAULT FALSE,"
+ input = append(input, id)
+ }
+ }
+ if len(input) > 0 {
+ _, err = r.db.Exec(baseQuery[:len(baseQuery)-1])
+ if err == nil {
+ for _, id := range input {
+ r.columns.Add(id, true)
+ }
+ }
+ }
+
+ return err
+}
+
+func (r *headerRepository) MarkHeaderChecked(headerID int64, id string) error {
+ _, err := r.db.Exec(`INSERT INTO public.checked_headers (header_id, `+id+`)
+ VALUES ($1, $2)
+ ON CONFLICT (header_id) DO
+ UPDATE SET `+id+` = $2`, headerID, true)
+
+ return err
+}
+
+func (r *headerRepository) MarkHeaderCheckedForAll(headerID int64, ids []string) error {
+ pgStr := "INSERT INTO public.checked_headers (header_id, "
+ for _, id := range ids {
+ pgStr += id + ", "
+ }
+ pgStr = pgStr[:len(pgStr)-2] + ") VALUES ($1, "
+ for i := 0; i < len(ids); i++ {
+ pgStr += "true, "
+ }
+ pgStr = pgStr[:len(pgStr)-2] + ") ON CONFLICT (header_id) DO UPDATE SET "
+ for _, id := range ids {
+ pgStr += fmt.Sprintf("%s = true, ", id)
+ }
+ pgStr = pgStr[:len(pgStr)-2]
+ _, err := r.db.Exec(pgStr, headerID)
+
+ return err
+}
+
+func (r *headerRepository) MarkHeadersCheckedForAll(headers []core.Header, ids []string) error {
+ tx, err := r.db.Begin()
+ if err != nil {
+ return err
+ }
+
+ for _, header := range headers {
+ pgStr := "INSERT INTO public.checked_headers (header_id, "
+ for _, id := range ids {
+ pgStr += id + ", "
+ }
+ pgStr = pgStr[:len(pgStr)-2] + ") VALUES ($1, "
+ for i := 0; i < len(ids); i++ {
+ pgStr += "true, "
+ }
+ pgStr = pgStr[:len(pgStr)-2] + ") ON CONFLICT (header_id) DO UPDATE SET "
+ for _, id := range ids {
+ pgStr += fmt.Sprintf("%s = true, ", id)
+ }
+ pgStr = pgStr[:len(pgStr)-2]
+ _, err = tx.Exec(pgStr, header.Id)
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+
+ return tx.Commit()
+}
+
+func (r *headerRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64, id string) ([]core.Header, error) {
+ var result []core.Header
+ var query string
+ var err error
+
+ if endingBlockNumber == -1 {
+ query = `SELECT headers.id, headers.block_number, headers.hash FROM headers
+ LEFT JOIN checked_headers on headers.id = header_id
+ WHERE (header_id ISNULL OR ` + id + ` IS FALSE)
+ AND headers.block_number >= $1
+ AND headers.eth_node_fingerprint = $2
+ ORDER BY headers.block_number`
+ err = r.db.Select(&result, query, startingBlockNumber, r.db.Node.ID)
+ } else {
+ query = `SELECT headers.id, headers.block_number, headers.hash FROM headers
+ LEFT JOIN checked_headers on headers.id = header_id
+ WHERE (header_id ISNULL OR ` + id + ` IS FALSE)
+ AND headers.block_number >= $1
+ AND headers.block_number <= $2
+ AND headers.eth_node_fingerprint = $3
+ ORDER BY headers.block_number`
+ err = r.db.Select(&result, query, startingBlockNumber, endingBlockNumber, r.db.Node.ID)
+ }
+
+ return result, err
+}
+
+func (r *headerRepository) MissingHeadersForAll(startingBlockNumber, endingBlockNumber int64, ids []string) ([]core.Header, error) {
+ var result []core.Header
+ var query string
+ var err error
+
+ baseQuery := `SELECT headers.id, headers.block_number, headers.hash FROM headers
+ LEFT JOIN checked_headers on headers.id = header_id
+ WHERE (header_id ISNULL`
+ for _, id := range ids {
+ baseQuery += ` OR ` + id + ` IS FALSE`
+ }
+
+ if endingBlockNumber == -1 {
+ endStr := `) AND headers.block_number >= $1
+ AND headers.eth_node_fingerprint = $2
+ ORDER BY headers.block_number`
+ query = baseQuery + endStr
+ err = r.db.Select(&result, query, startingBlockNumber, r.db.Node.ID)
+ } else {
+ endStr := `) AND headers.block_number >= $1
+ AND headers.block_number <= $2
+ AND headers.eth_node_fingerprint = $3
+ ORDER BY headers.block_number`
+ query = baseQuery + endStr
+ err = r.db.Select(&result, query, startingBlockNumber, endingBlockNumber, r.db.Node.ID)
+ }
+
+ return result, err
+}
+
+func (r *headerRepository) MissingMethodsCheckedEventsIntersection(startingBlockNumber, endingBlockNumber int64, methodIds, eventIds []string) ([]core.Header, error) {
+ var result []core.Header
+ var query string
+ var err error
+
+ baseQuery := `SELECT headers.id, headers.block_number, headers.hash FROM headers
+ LEFT JOIN checked_headers on headers.id = header_id
+ WHERE (header_id IS NOT NULL`
+ for _, id := range eventIds {
+ baseQuery += ` AND ` + id + ` IS TRUE`
+ }
+ baseQuery += `) AND (`
+ for _, id := range methodIds {
+ baseQuery += id + ` IS FALSE AND `
+ }
+ baseQuery = baseQuery[:len(baseQuery)-5] + `) `
+
+ if endingBlockNumber == -1 {
+ endStr := `AND headers.block_number >= $1
+ AND headers.eth_node_fingerprint = $2
+ ORDER BY headers.block_number`
+ query = baseQuery + endStr
+ err = r.db.Select(&result, query, startingBlockNumber, r.db.Node.ID)
+ } else {
+ endStr := `AND headers.block_number >= $1
+ AND headers.block_number <= $2
+ AND headers.eth_node_fingerprint = $3
+ ORDER BY headers.block_number`
+ query = baseQuery + endStr
+ err = r.db.Select(&result, query, startingBlockNumber, endingBlockNumber, r.db.Node.ID)
+ }
+
+ return result, err
+}
+
+func (r *headerRepository) CheckCache(key string) (interface{}, bool) {
+ return r.columns.Get(key)
+}
+
+func MarkHeaderCheckedInTransaction(headerID int64, tx *sql.Tx, eventID string) error {
+ _, err := tx.Exec(`INSERT INTO public.checked_headers (header_id, `+eventID+`)
+ VALUES ($1, $2)
+ ON CONFLICT (header_id) DO
+ UPDATE SET `+eventID+` = $2`, headerID, true)
+ return err
+}
diff --git a/pkg/omni/light/repository/header_repository_test.go b/pkg/omni/light/repository/header_repository_test.go
new file mode 100644
index 00000000..4f25cabc
--- /dev/null
+++ b/pkg/omni/light/repository/header_repository_test.go
@@ -0,0 +1,317 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository_test
+
+import (
+ "fmt"
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+)
+
+var _ = Describe("Repository", func() {
+ var db *postgres.DB
+ var omniHeaderRepo repository.HeaderRepository // omni/light header repository
+ var coreHeaderRepo repositories.HeaderRepository // pkg/datastore header repository
+ var eventIDs = []string{
+ "eventName_contractAddr",
+ "eventName_contractAddr2",
+ "eventName_contractAddr3",
+ }
+ var methodIDs = []string{
+ "methodName_contractAddr",
+ "methodName_contractAddr2",
+ "methodName_contractAddr3",
+ }
+
+ BeforeEach(func() {
+ db, _ = test_helpers.SetupDBandBC()
+ omniHeaderRepo = repository.NewHeaderRepository(db)
+ coreHeaderRepo = repositories.NewHeaderRepository(db)
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("AddCheckColumn", func() {
+ It("Creates a column for the given eventID to mark if the header has been checked for that event", func() {
+ query := fmt.Sprintf("SELECT %s FROM checked_headers", eventIDs[0])
+ _, err := db.Exec(query)
+ Expect(err).To(HaveOccurred())
+
+ err = omniHeaderRepo.AddCheckColumn(eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ _, err = db.Exec(query)
+ Expect(err).ToNot(HaveOccurred())
+ })
+
+ It("Caches column it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ _, ok := omniHeaderRepo.CheckCache(eventIDs[0])
+ Expect(ok).To(Equal(false))
+
+ err := omniHeaderRepo.AddCheckColumn(eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ v, ok := omniHeaderRepo.CheckCache(eventIDs[0])
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("AddCheckColumns", func() {
+ It("Creates a column for the given eventIDs to mark if the header has been checked for those events", func() {
+ for _, id := range eventIDs {
+ _, err := db.Exec(fmt.Sprintf("SELECT %s FROM checked_headers", id))
+ Expect(err).To(HaveOccurred())
+ }
+
+ err := omniHeaderRepo.AddCheckColumns(eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+
+ for _, id := range eventIDs {
+ _, err := db.Exec(fmt.Sprintf("SELECT %s FROM checked_headers", id))
+ Expect(err).ToNot(HaveOccurred())
+ }
+ })
+
+ It("Caches columns it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ for _, id := range eventIDs {
+ _, ok := omniHeaderRepo.CheckCache(id)
+ Expect(ok).To(Equal(false))
+ }
+
+ err := omniHeaderRepo.AddCheckColumns(eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+
+ for _, id := range eventIDs {
+ v, ok := omniHeaderRepo.CheckCache(id)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ }
+ })
+ })
+
+ Describe("MissingHeaders", func() {
+ It("Returns all unchecked headers for the given eventID", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumn(eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err := omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+ })
+
+ It("Returns unchecked headers in ascending order", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumn(eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err := omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+
+ h1 := missingHeaders[0]
+ h2 := missingHeaders[1]
+ h3 := missingHeaders[2]
+ Expect(h1.BlockNumber).To(Equal(int64(6194632)))
+ Expect(h2.BlockNumber).To(Equal(int64(6194633)))
+ Expect(h3.BlockNumber).To(Equal(int64(6194634)))
+ })
+
+ It("Fails if eventID does not yet exist in check_headers table", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumn(eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ _, err = omniHeaderRepo.MissingHeaders(6194630, 6194635, "notEventId")
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("MissingHeadersForAll", func() { // HERE
+ It("Returns all headers that have not been checked for all of the ids provided", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumns(eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err := omniHeaderRepo.MissingHeadersForAll(6194630, 6194635, eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+
+ err = omniHeaderRepo.MarkHeaderChecked(missingHeaders[0].Id, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err = omniHeaderRepo.MissingHeadersForAll(6194630, 6194635, eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+
+ err = omniHeaderRepo.MarkHeaderChecked(missingHeaders[0].Id, eventIDs[1])
+ Expect(err).ToNot(HaveOccurred())
+ err = omniHeaderRepo.MarkHeaderChecked(missingHeaders[0].Id, eventIDs[2])
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err = omniHeaderRepo.MissingHeadersForAll(6194630, 6194635, eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(2))
+ })
+
+ It("Fails if one of the eventIDs does not yet exist in check_headers table", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumns(eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+ badEventIDs := append(eventIDs, "notEventId")
+
+ _, err = omniHeaderRepo.MissingHeadersForAll(6194630, 6194635, badEventIDs)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("MarkHeaderChecked", func() {
+ It("Marks the header checked for the given eventID", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumn(eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err := omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+
+ headerID := missingHeaders[0].Id
+ err = omniHeaderRepo.MarkHeaderChecked(headerID, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err = omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(2))
+ })
+
+ It("Fails if eventID does not yet exist in check_headers table", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumn(eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err := omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+
+ headerID := missingHeaders[0].Id
+ err = omniHeaderRepo.MarkHeaderChecked(headerID, "notEventId")
+ Expect(err).To(HaveOccurred())
+
+ missingHeaders, err = omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+ })
+ })
+
+ Describe("MarkHeaderCheckedForAll", func() {
+ It("Marks the header checked for all provided column ids", func() {
+ addHeaders(coreHeaderRepo)
+ err := omniHeaderRepo.AddCheckColumns(eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err := omniHeaderRepo.MissingHeadersForAll(6194630, 6194635, eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+
+ headerID := missingHeaders[0].Id
+ err = omniHeaderRepo.MarkHeaderCheckedForAll(headerID, eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+
+ missingHeaders, err = omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(2))
+ })
+ })
+
+ Describe("MarkHeadersCheckedForAll", func() {
+ It("Marks the headers checked for all provided column ids", func() {
+ addHeaders(coreHeaderRepo)
+ methodIDs := []string{
+ "methodName_contractAddr",
+ "methodName_contractAddr2",
+ "methodName_contractAddr3",
+ }
+
+ var missingHeaders []core.Header
+ for _, id := range methodIDs {
+ err := omniHeaderRepo.AddCheckColumn(id)
+ Expect(err).ToNot(HaveOccurred())
+ missingHeaders, err = omniHeaderRepo.MissingHeaders(6194630, 6194635, id)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+ }
+
+ err := omniHeaderRepo.MarkHeadersCheckedForAll(missingHeaders, methodIDs)
+ Expect(err).ToNot(HaveOccurred())
+ for _, id := range methodIDs {
+ missingHeaders, err = omniHeaderRepo.MissingHeaders(6194630, 6194635, id)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(0))
+ }
+ })
+ })
+
+ Describe("MissingMethodsCheckedEventsIntersection", func() {
+ It("Returns headers that have been checked for all the provided events but have not been checked for all the provided methods", func() {
+ addHeaders(coreHeaderRepo)
+ for i, id := range eventIDs {
+ err := omniHeaderRepo.AddCheckColumn(id)
+ Expect(err).ToNot(HaveOccurred())
+ err = omniHeaderRepo.AddCheckColumn(methodIDs[i])
+ Expect(err).ToNot(HaveOccurred())
+ }
+
+ missingHeaders, err := omniHeaderRepo.MissingHeaders(6194630, 6194635, eventIDs[0])
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(missingHeaders)).To(Equal(3))
+
+ headerID := missingHeaders[0].Id
+ headerID2 := missingHeaders[1].Id
+ for i, id := range eventIDs {
+ err = omniHeaderRepo.MarkHeaderChecked(headerID, id)
+ Expect(err).ToNot(HaveOccurred())
+ err = omniHeaderRepo.MarkHeaderChecked(headerID2, id)
+ Expect(err).ToNot(HaveOccurred())
+ err = omniHeaderRepo.MarkHeaderChecked(headerID, methodIDs[i])
+ Expect(err).ToNot(HaveOccurred())
+ }
+
+ intersectionHeaders, err := omniHeaderRepo.MissingMethodsCheckedEventsIntersection(6194630, 6194635, methodIDs, eventIDs)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(intersectionHeaders)).To(Equal(1))
+ Expect(intersectionHeaders[0].Id).To(Equal(headerID2))
+
+ })
+ })
+})
+
+func addHeaders(coreHeaderRepo repositories.HeaderRepository) {
+ coreHeaderRepo.CreateOrUpdateHeader(mocks.MockHeader1)
+ coreHeaderRepo.CreateOrUpdateHeader(mocks.MockHeader2)
+ coreHeaderRepo.CreateOrUpdateHeader(mocks.MockHeader3)
+}
diff --git a/pkg/omni/light/repository/repository_suite_test.go b/pkg/omni/light/repository/repository_suite_test.go
new file mode 100644
index 00000000..80215953
--- /dev/null
+++ b/pkg/omni/light/repository/repository_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestRepository(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Light Repository Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/light/retriever/block_retriever.go b/pkg/omni/light/retriever/block_retriever.go
new file mode 100644
index 00000000..a871278e
--- /dev/null
+++ b/pkg/omni/light/retriever/block_retriever.go
@@ -0,0 +1,60 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever
+
+import (
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+)
+
+// Block retriever is used to retrieve the first block for a given contract and the most recent block
+// It requires a vDB synced database with blocks, transactions, receipts, and logs
+type BlockRetriever interface {
+ RetrieveFirstBlock() (int64, error)
+ RetrieveMostRecentBlock() (int64, error)
+}
+
+type blockRetriever struct {
+ db *postgres.DB
+}
+
+func NewBlockRetriever(db *postgres.DB) (r *blockRetriever) {
+ return &blockRetriever{
+ db: db,
+ }
+}
+
+// Retrieve block number of earliest header in repo
+func (r *blockRetriever) RetrieveFirstBlock() (int64, error) {
+ var firstBlock int
+ err := r.db.Get(
+ &firstBlock,
+ "SELECT block_number FROM headers ORDER BY block_number LIMIT 1",
+ )
+
+ return int64(firstBlock), err
+}
+
+// Retrieve block number of latest header in repo
+func (r *blockRetriever) RetrieveMostRecentBlock() (int64, error) {
+ var lastBlock int
+ err := r.db.Get(
+ &lastBlock,
+ "SELECT block_number FROM headers ORDER BY block_number DESC LIMIT 1",
+ )
+
+ return int64(lastBlock), err
+}
diff --git a/pkg/omni/light/retriever/block_retriever_test.go b/pkg/omni/light/retriever/block_retriever_test.go
new file mode 100644
index 00000000..563e3738
--- /dev/null
+++ b/pkg/omni/light/retriever/block_retriever_test.go
@@ -0,0 +1,79 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever_test
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/retriever"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+)
+
+var _ = Describe("Block Retriever", func() {
+ var db *postgres.DB
+ var r retriever.BlockRetriever
+ var headerRepository repositories.HeaderRepository
+
+ BeforeEach(func() {
+ db, _ = test_helpers.SetupDBandBC()
+ headerRepository = repositories.NewHeaderRepository(db)
+ r = retriever.NewBlockRetriever(db)
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("RetrieveFirstBlock", func() {
+ It("Retrieves block number of earliest header in the database", func() {
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader1)
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader2)
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader3)
+
+ i, err := r.RetrieveFirstBlock()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(i).To(Equal(int64(6194632)))
+ })
+
+ It("Fails if no headers can be found in the database", func() {
+ _, err := r.RetrieveFirstBlock()
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("RetrieveMostRecentBlock", func() {
+ It("Retrieves the latest header's block number", func() {
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader1)
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader2)
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader3)
+
+ i, err := r.RetrieveMostRecentBlock()
+ Expect(err).ToNot(HaveOccurred())
+ Expect(i).To(Equal(int64(6194634)))
+ })
+
+ It("Fails if no headers can be found in the database", func() {
+ i, err := r.RetrieveMostRecentBlock()
+ Expect(err).To(HaveOccurred())
+ Expect(i).To(Equal(int64(0)))
+ })
+ })
+})
diff --git a/pkg/omni/light/retriever/retriever_suite_test.go b/pkg/omni/light/retriever/retriever_suite_test.go
new file mode 100644
index 00000000..cb5a7313
--- /dev/null
+++ b/pkg/omni/light/retriever/retriever_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestRetriever(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Light BLock Number Retriever Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/light/transformer/transformer.go b/pkg/omni/light/transformer/transformer.go
new file mode 100644
index 00000000..565e6966
--- /dev/null
+++ b/pkg/omni/light/transformer/transformer.go
@@ -0,0 +1,376 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer
+
+import (
+ "errors"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+ gethTypes "github.com/ethereum/go-ethereum/core/types"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/converter"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/fetcher"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/retriever"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/parser"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/poller"
+ srep "github.com/vulcanize/vulcanizedb/pkg/omni/shared/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+// Requires a light synced vDB (headers) and a running eth node (or infura)
+type transformer struct {
+ // Database interfaces
+ srep.EventRepository // Holds transformed watched event log data
+ repository.HeaderRepository // Interface for interaction with header repositories
+
+ // Pre-processing interfaces
+ parser.Parser // Parses events and methods out of contract abi fetched using contract address
+ retriever.BlockRetriever // Retrieves first block for contract and current block height
+
+ // Processing interfaces
+ fetcher.Fetcher // Fetches event logs, using header hashes
+ converter.Converter // Converts watched event logs into custom log
+ poller.Poller // Polls methods using arguments collected from events and persists them using a method datastore
+
+ // Ethereum network name; default "" is mainnet
+ Network string
+
+ // Store contract info as mapping to contract address
+ Contracts map[string]*contract.Contract
+
+ // Targeted subset of events/methods
+ // Stored as maps of contract address to events/method names of interest
+ WatchedEvents map[string][]string // Default/empty event list means all are watched
+ WantedMethods map[string][]string // Default/empty method list means none are polled
+
+ // Starting block number for each contract
+ ContractStart map[string]int64
+
+ // Lists of argument values to filter event or
+ // method data with; if empty no filter is applied
+ EventArgs map[string][]string
+ MethodArgs map[string][]string
+
+ // Whether or not to create a list of emitted address or hashes for the contract in postgres
+ CreateAddrList map[string]bool
+ CreateHashList map[string]bool
+
+ // Method piping on/off for a contract
+ Piping map[string]bool
+
+ // Internally configured transformer variables
+ contractAddresses []string // Holds all contract addresses, for batch fetching of logs
+ sortedEventIds map[string][]string // Map to sort event column ids by contract, for post fetch processing and persisting of logs
+ sortedMethodIds map[string][]string // Map to sort method column ids by contract, for post fetch method polling
+ eventIds []string // Holds event column ids across all contract, for batch fetching of headers
+ eventFilters []common.Hash // Holds topic0 hashes across all contracts, for batch fetching of logs
+ start int64 // Hold the lowest starting block and the highest ending block
+}
+
+// Order-of-operations:
+// 1. Create new transformer
+// 2. Load contract addresses and their parameters
+// 3. Init
+// 4. Execute
+
+// Transformer takes in config for blockchain, database, and network id
+func NewTransformer(network string, bc core.BlockChain, db *postgres.DB) *transformer {
+
+ return &transformer{
+ Poller: poller.NewPoller(bc, db, types.LightSync),
+ Fetcher: fetcher.NewFetcher(bc),
+ Parser: parser.NewParser(network),
+ HeaderRepository: repository.NewHeaderRepository(db),
+ BlockRetriever: retriever.NewBlockRetriever(db),
+ Converter: converter.NewConverter(&contract.Contract{}),
+ Contracts: map[string]*contract.Contract{},
+ EventRepository: srep.NewEventRepository(db, types.LightSync),
+ WatchedEvents: map[string][]string{},
+ WantedMethods: map[string][]string{},
+ ContractStart: map[string]int64{},
+ EventArgs: map[string][]string{},
+ MethodArgs: map[string][]string{},
+ CreateAddrList: map[string]bool{},
+ CreateHashList: map[string]bool{},
+ Piping: map[string]bool{},
+ Network: network,
+ }
+}
+
+// Use after creating and setting transformer
+// Loops over all of the addr => filter sets
+// Uses parser to pull event info from abi
+// Use this info to generate event filters
+func (tr *transformer) Init() error {
+ // Initialize internally configured transformer settings
+ tr.contractAddresses = make([]string, 0) // Holds all contract addresses, for batch fetching of logs
+ tr.sortedEventIds = make(map[string][]string) // Map to sort event column ids by contract, for post fetch processing and persisting of logs
+ tr.sortedMethodIds = make(map[string][]string) // Map to sort method column ids by contract, for post fetch method polling
+ tr.eventIds = make([]string, 0) // Holds event column ids across all contract, for batch fetching of headers
+ tr.eventFilters = make([]common.Hash, 0) // Holds topic0 hashes across all contracts, for batch fetching of logs
+ tr.start = 100000000000 // Hold the lowest starting block and the highest ending block
+
+ // Iterate through all internal contract addresses
+ for contractAddr, subset := range tr.WatchedEvents {
+ // Get Abi
+ err := tr.Parser.Parse(contractAddr)
+ if err != nil {
+ return err
+ }
+
+ // Get first block and most recent block number in the header repo
+ firstBlock, err := tr.BlockRetriever.RetrieveFirstBlock()
+ if err != nil {
+ return err
+ }
+ lastBlock, err := tr.BlockRetriever.RetrieveMostRecentBlock()
+ if err != nil {
+ return err
+ }
+
+ // Set to specified range if it falls within the bounds
+ if firstBlock < tr.ContractStart[contractAddr] {
+ firstBlock = tr.ContractStart[contractAddr]
+ }
+
+ // Get contract name if it has one
+ var name = new(string)
+ tr.FetchContractData(tr.Abi(), contractAddr, "name", nil, &name, lastBlock)
+
+ // Remove any potential accidental duplicate inputs in arg filter values
+ eventArgs := map[string]bool{}
+ for _, arg := range tr.EventArgs[contractAddr] {
+ eventArgs[arg] = true
+ }
+ methodArgs := map[string]bool{}
+ for _, arg := range tr.MethodArgs[contractAddr] {
+ methodArgs[arg] = true
+ }
+
+ // Aggregate info into contract object and store for execution
+ con := contract.Contract{
+ Name: *name,
+ Network: tr.Network,
+ Address: contractAddr,
+ Abi: tr.Parser.Abi(),
+ ParsedAbi: tr.Parser.ParsedAbi(),
+ StartingBlock: firstBlock,
+ LastBlock: -1,
+ Events: tr.Parser.GetEvents(subset),
+ Methods: tr.Parser.GetSelectMethods(tr.WantedMethods[contractAddr]),
+ FilterArgs: eventArgs,
+ MethodArgs: methodArgs,
+ CreateAddrList: tr.CreateAddrList[contractAddr],
+ CreateHashList: tr.CreateHashList[contractAddr],
+ Piping: tr.Piping[contractAddr],
+ }.Init()
+ tr.Contracts[contractAddr] = con
+ tr.contractAddresses = append(tr.contractAddresses, con.Address)
+
+ // Create checked_headers columns for each event id and append to list of all event ids
+ tr.sortedEventIds[con.Address] = make([]string, 0, len(con.Events))
+ for _, event := range con.Events {
+ eventId := strings.ToLower(event.Name + "_" + con.Address)
+ err := tr.HeaderRepository.AddCheckColumn(eventId)
+ if err != nil {
+ return err
+ }
+ // Keep track of this event id; sorted and unsorted
+ tr.sortedEventIds[con.Address] = append(tr.sortedEventIds[con.Address], eventId)
+ tr.eventIds = append(tr.eventIds, eventId)
+ // Append this event sig to the filters
+ tr.eventFilters = append(tr.eventFilters, event.Sig())
+ }
+
+ // Create checked_headers columns for each method id and append list of all method ids
+ tr.sortedMethodIds[con.Address] = make([]string, 0, len(con.Methods))
+ for _, m := range con.Methods {
+ methodId := strings.ToLower(m.Name + "_" + con.Address)
+ err := tr.HeaderRepository.AddCheckColumn(methodId)
+ if err != nil {
+ return err
+ }
+ tr.sortedMethodIds[con.Address] = append(tr.sortedMethodIds[con.Address], methodId)
+ }
+
+ // Update start to the lowest block
+ if con.StartingBlock < tr.start {
+ tr.start = con.StartingBlock
+ }
+ }
+
+ return nil
+}
+
+func (tr *transformer) Execute() error {
+ if len(tr.Contracts) == 0 {
+ return errors.New("error: transformer has no initialized contracts")
+ }
+
+ // Map to sort batch fetched logs by which contract they belong to, for post fetch processing
+ sortedLogs := make(map[string][]gethTypes.Log)
+ for _, con := range tr.Contracts {
+ sortedLogs[con.Address] = []gethTypes.Log{}
+ }
+
+ // Find unchecked headers for all events across all contracts; these are returned in asc order
+ missingHeaders, err := tr.HeaderRepository.MissingHeadersForAll(tr.start, -1, tr.eventIds)
+ if err != nil {
+ return err
+ }
+
+ // Iterate over headers
+ for _, header := range missingHeaders {
+ // And fetch all event logs across contracts at this header
+ allLogs, err := tr.Fetcher.FetchLogs(tr.contractAddresses, tr.eventFilters, header)
+ if err != nil {
+ return err
+ }
+
+ // If no logs are found mark the header checked for all of these eventIDs
+ // and continue to method polling and onto the next iteration
+ if len(allLogs) < 1 {
+ err = tr.HeaderRepository.MarkHeaderCheckedForAll(header.Id, tr.eventIds)
+ if err != nil {
+ return err
+ }
+ err = tr.methodPolling(header, tr.sortedMethodIds)
+ if err != nil {
+ return err
+ }
+ continue
+ }
+
+ // Sort logs by the contract they belong to
+ for _, log := range allLogs {
+ addr := strings.ToLower(log.Address.Hex())
+ sortedLogs[addr] = append(sortedLogs[addr], log)
+ }
+
+ // Process logs for each contract
+ for conAddr, logs := range sortedLogs {
+ if logs == nil {
+ continue
+ }
+ // Configure converter with this contract
+ con := tr.Contracts[conAddr]
+ tr.Converter.Update(con)
+
+ // Convert logs into batches of log mappings (eventName => []types.Logs
+ convertedLogs, err := tr.Converter.ConvertBatch(logs, con.Events, header.Id)
+ if err != nil {
+ return err
+ }
+ // Cycle through each type of event log and persist them
+ for eventName, logs := range convertedLogs {
+ // If logs for this event are empty, mark them checked at this header and continue
+ if len(logs) < 1 {
+ eventId := strings.ToLower(eventName + "_" + con.Address)
+ err = tr.HeaderRepository.MarkHeaderChecked(header.Id, eventId)
+ if err != nil {
+ return err
+ }
+ continue
+ }
+ // If logs aren't empty, persist them
+ // Header is marked checked in the transactions
+ err = tr.EventRepository.PersistLogs(logs, con.Events[eventName], con.Address, con.Name)
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ // Poll contracts at this block height
+ err = tr.methodPolling(header, tr.sortedMethodIds)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Used to poll contract methods at a given header
+func (tr *transformer) methodPolling(header core.Header, sortedMethodIds map[string][]string) error {
+ for _, con := range tr.Contracts {
+ // Skip method polling processes if no methods are specified
+ // Also don't try to poll methods below this contract's specified starting block
+ if len(con.Methods) == 0 || header.BlockNumber < con.StartingBlock {
+ continue
+ }
+
+ // Poll all methods for this contract at this header
+ err := tr.Poller.PollContractAt(*con, header.BlockNumber)
+ if err != nil {
+ return err
+ }
+
+ // Mark this header checked for the methods
+ err = tr.HeaderRepository.MarkHeaderCheckedForAll(header.Id, sortedMethodIds[con.Address])
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Used to set which contract addresses and which of their events to watch
+func (tr *transformer) SetEvents(contractAddr string, filterSet []string) {
+ tr.WatchedEvents[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set subset of account addresses to watch events for
+func (tr *transformer) SetEventArgs(contractAddr string, filterSet []string) {
+ tr.EventArgs[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set which contract addresses and which of their methods to call
+func (tr *transformer) SetMethods(contractAddr string, filterSet []string) {
+ tr.WantedMethods[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set subset of account addresses to poll methods on
+func (tr *transformer) SetMethodArgs(contractAddr string, filterSet []string) {
+ tr.MethodArgs[strings.ToLower(contractAddr)] = filterSet
+}
+
+// Used to set the block range to watch for a given address
+func (tr *transformer) SetStartingBlock(contractAddr string, start int64) {
+ tr.ContractStart[strings.ToLower(contractAddr)] = start
+}
+
+// Used to set whether or not to persist an account address list
+func (tr *transformer) SetCreateAddrList(contractAddr string, on bool) {
+ tr.CreateAddrList[strings.ToLower(contractAddr)] = on
+}
+
+// Used to set whether or not to persist an hash list
+func (tr *transformer) SetCreateHashList(contractAddr string, on bool) {
+ tr.CreateHashList[strings.ToLower(contractAddr)] = on
+}
+
+// Used to turn method piping on for a contract
+func (tr *transformer) SetPiping(contractAddr string, on bool) {
+ tr.Piping[strings.ToLower(contractAddr)] = on
+}
diff --git a/pkg/omni/light/transformer/transformer_suite_test.go b/pkg/omni/light/transformer/transformer_suite_test.go
new file mode 100644
index 00000000..52ab1197
--- /dev/null
+++ b/pkg/omni/light/transformer/transformer_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestTransformer(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Light Transformer Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/light/transformer/transformer_test.go b/pkg/omni/light/transformer/transformer_test.go
new file mode 100644
index 00000000..db805532
--- /dev/null
+++ b/pkg/omni/light/transformer/transformer_test.go
@@ -0,0 +1,507 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer_test
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/transformer"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+)
+
+var _ = Describe("Transformer", func() {
+ var db *postgres.DB
+ var err error
+ var blockChain core.BlockChain
+ var headerRepository repositories.HeaderRepository
+ var headerID, headerID2 int64
+ var ensAddr = strings.ToLower(constants.EnsContractAddress)
+ var tusdAddr = strings.ToLower(constants.TusdContractAddress)
+
+ BeforeEach(func() {
+ db, blockChain = test_helpers.SetupDBandBC()
+ headerRepository = repositories.NewHeaderRepository(db)
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("SetEvents", func() {
+ It("Sets which events to watch from the given contract address", func() {
+ watchedEvents := []string{"Transfer", "Mint"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, watchedEvents)
+ Expect(t.WatchedEvents[tusdAddr]).To(Equal(watchedEvents))
+ })
+ })
+
+ Describe("SetEventAddrs", func() {
+ It("Sets which account addresses to watch events for", func() {
+ eventAddrs := []string{"test1", "test2"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEventArgs(constants.TusdContractAddress, eventAddrs)
+ Expect(t.EventArgs[tusdAddr]).To(Equal(eventAddrs))
+ })
+ })
+
+ Describe("SetMethods", func() {
+ It("Sets which methods to poll at the given contract address", func() {
+ watchedMethods := []string{"balanceOf", "totalSupply"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetMethods(constants.TusdContractAddress, watchedMethods)
+ Expect(t.WantedMethods[tusdAddr]).To(Equal(watchedMethods))
+ })
+ })
+
+ Describe("SetMethodAddrs", func() {
+ It("Sets which account addresses to poll methods against", func() {
+ methodAddrs := []string{"test1", "test2"}
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetMethodArgs(constants.TusdContractAddress, methodAddrs)
+ Expect(t.MethodArgs[tusdAddr]).To(Equal(methodAddrs))
+ })
+ })
+
+ Describe("SetStartingBlock", func() {
+ It("Sets the block range that the contract should be watched within", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetStartingBlock(constants.TusdContractAddress, 11)
+ Expect(t.ContractStart[tusdAddr]).To(Equal(int64(11)))
+ })
+ })
+
+ Describe("SetCreateAddrList", func() {
+ It("Sets the block range that the contract should be watched within", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetCreateAddrList(constants.TusdContractAddress, true)
+ Expect(t.CreateAddrList[tusdAddr]).To(Equal(true))
+ })
+ })
+
+ Describe("SetCreateHashList", func() {
+ It("Sets the block range that the contract should be watched within", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetCreateHashList(constants.TusdContractAddress, true)
+ Expect(t.CreateHashList[tusdAddr]).To(Equal(true))
+ })
+ })
+
+ Describe("Init", func() {
+ It("Initializes transformer's contract objects", func() {
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader1)
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader3)
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ c, ok := t.Contracts[tusdAddr]
+ Expect(ok).To(Equal(true))
+
+ Expect(c.StartingBlock).To(Equal(int64(6194632)))
+ Expect(c.LastBlock).To(Equal(int64(-1)))
+ Expect(c.Abi).To(Equal(constants.TusdAbiString))
+ Expect(c.Name).To(Equal("TrueUSD"))
+ Expect(c.Address).To(Equal(tusdAddr))
+ })
+
+ It("Fails to initialize if first and most recent block numbers cannot be fetched from vDB headers table", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ err = t.Init()
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("Does nothing if watched events are unset", func() {
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader1)
+ headerRepository.CreateOrUpdateHeader(mocks.MockHeader3)
+ t := transformer.NewTransformer("", blockChain, db)
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+
+ _, ok := t.Contracts[tusdAddr]
+ Expect(ok).To(Equal(false))
+ })
+ })
+
+ Describe("Execute- against TrueUSD contract", func() {
+ BeforeEach(func() {
+ header1, err := blockChain.GetHeaderByNumber(6791668)
+ Expect(err).ToNot(HaveOccurred())
+ header2, err := blockChain.GetHeaderByNumber(6791669)
+ Expect(err).ToNot(HaveOccurred())
+ header3, err := blockChain.GetHeaderByNumber(6791670)
+ Expect(err).ToNot(HaveOccurred())
+ headerRepository.CreateOrUpdateHeader(header1)
+ headerID, err = headerRepository.CreateOrUpdateHeader(header2)
+ Expect(err).ToNot(HaveOccurred())
+ headerRepository.CreateOrUpdateHeader(header3)
+ })
+
+ It("Transforms watched contract data into custom repositories", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, nil)
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ log := test_helpers.LightTransferLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.transfer_event", tusdAddr)).StructScan(&log)
+ Expect(err).ToNot(HaveOccurred())
+ // We don't know vulcID, so compare individual fields instead of complete structures
+ Expect(log.HeaderID).To(Equal(headerID))
+ Expect(log.From).To(Equal("0x1062a747393198f70F71ec65A582423Dba7E5Ab3"))
+ Expect(log.To).To(Equal("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0"))
+ Expect(log.Value).To(Equal("9998940000000000000000"))
+ })
+
+ It("Keeps track of contract-related addresses while transforming event data if they need to be used for later method polling", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ c, ok := t.Contracts[tusdAddr]
+ Expect(ok).To(Equal(true))
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(c.EmittedAddrs)).To(Equal(4))
+ Expect(len(c.EmittedHashes)).To(Equal(0))
+
+ b, ok := c.EmittedAddrs[common.HexToAddress("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = c.EmittedAddrs[common.HexToAddress("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = c.EmittedAddrs[common.HexToAddress("0x571A326f5B15E16917dC17761c340c1ec5d06f6d")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = c.EmittedAddrs[common.HexToAddress("0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843b1234567890")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = c.EmittedAddrs[""]
+ Expect(ok).To(Equal(false))
+
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x09THISE21a5IS5cFAKE1D82fAND43bCE06MADEUP")]
+ Expect(ok).To(Equal(false))
+ })
+
+ It("Polls given methods using generated token holder address", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ res := test_helpers.BalanceOf{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x1062a747393198f70F71ec65A582423Dba7E5Ab3' AND block = '6791669'", tusdAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Balance).To(Equal("55849938025000000000000"))
+ Expect(res.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x09BbBBE21a5975cAc061D82f7b843b1234567890' AND block = '6791669'", tusdAddr)).StructScan(&res)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("Fails if initialization has not been done", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, nil)
+ err = t.Execute()
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("Execute- against ENS registry contract", func() {
+ BeforeEach(func() {
+ header1, err := blockChain.GetHeaderByNumber(6885695)
+ Expect(err).ToNot(HaveOccurred())
+ header2, err := blockChain.GetHeaderByNumber(6885696)
+ Expect(err).ToNot(HaveOccurred())
+ header3, err := blockChain.GetHeaderByNumber(6885697)
+ Expect(err).ToNot(HaveOccurred())
+ headerRepository.CreateOrUpdateHeader(header1)
+ headerID, err = headerRepository.CreateOrUpdateHeader(header2)
+ Expect(err).ToNot(HaveOccurred())
+ headerRepository.CreateOrUpdateHeader(header3)
+ })
+
+ It("Transforms watched contract data into custom repositories", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, nil)
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ log := test_helpers.LightNewOwnerLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&log)
+ Expect(err).ToNot(HaveOccurred())
+ // We don't know vulcID, so compare individual fields instead of complete structures
+ Expect(log.HeaderID).To(Equal(headerID))
+ Expect(log.Node).To(Equal("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"))
+ Expect(log.Label).To(Equal("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047"))
+ Expect(log.Owner).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef"))
+ })
+
+ It("Keeps track of contract-related hashes while transforming event data if they need to be used for later method polling", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ c, ok := t.Contracts[ensAddr]
+ Expect(ok).To(Equal(true))
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(c.EmittedHashes)).To(Equal(2))
+ Expect(len(c.EmittedAddrs)).To(Equal(0))
+
+ b, ok := c.EmittedHashes[common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = c.EmittedHashes[common.HexToHash("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ // Doesn't keep track of address since it wouldn't be used in calling the 'owner' method
+ _, ok = c.EmittedAddrs[common.HexToAddress("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef")]
+ Expect(ok).To(Equal(false))
+ })
+
+ It("Polls given method using list of collected hashes", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ res := test_helpers.Owner{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef"))
+ Expect(res.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000"))
+ Expect(res.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHIS288IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&res)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("It does not persist events if they do not pass the emitted arg filter", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, nil)
+ t.SetEventArgs(constants.EnsContractAddress, []string{"fake_filter_value"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ log := test_helpers.LightNewOwnerLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&log)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("If a method arg filter is applied, only those arguments are used in polling", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ t.SetMethodArgs(constants.EnsContractAddress, []string{"0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ res := test_helpers.Owner{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&res)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(res.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef"))
+ Expect(res.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&res)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("Execute- against both ENS and TrueUSD", func() {
+ BeforeEach(func() {
+ header1, err := blockChain.GetHeaderByNumber(6791668)
+ Expect(err).ToNot(HaveOccurred())
+ header2, err := blockChain.GetHeaderByNumber(6791669)
+ Expect(err).ToNot(HaveOccurred())
+ header3, err := blockChain.GetHeaderByNumber(6791670)
+ Expect(err).ToNot(HaveOccurred())
+ header4, err := blockChain.GetHeaderByNumber(6885695)
+ Expect(err).ToNot(HaveOccurred())
+ header5, err := blockChain.GetHeaderByNumber(6885696)
+ Expect(err).ToNot(HaveOccurred())
+ header6, err := blockChain.GetHeaderByNumber(6885697)
+ Expect(err).ToNot(HaveOccurred())
+ headerRepository.CreateOrUpdateHeader(header1)
+ headerID, err = headerRepository.CreateOrUpdateHeader(header2)
+ Expect(err).ToNot(HaveOccurred())
+ headerRepository.CreateOrUpdateHeader(header3)
+ headerRepository.CreateOrUpdateHeader(header4)
+ headerID2, err = headerRepository.CreateOrUpdateHeader(header5)
+ Expect(err).ToNot(HaveOccurred())
+ headerRepository.CreateOrUpdateHeader(header6)
+ })
+
+ It("Transforms watched contract data into custom repositories", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, nil)
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, nil)
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ newOwnerLog := test_helpers.LightNewOwnerLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.newowner_event", ensAddr)).StructScan(&newOwnerLog)
+ Expect(err).ToNot(HaveOccurred())
+ // We don't know vulcID, so compare individual fields instead of complete structures
+ Expect(newOwnerLog.HeaderID).To(Equal(headerID2))
+ Expect(newOwnerLog.Node).To(Equal("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"))
+ Expect(newOwnerLog.Label).To(Equal("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047"))
+ Expect(newOwnerLog.Owner).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef"))
+
+ transferLog := test_helpers.LightTransferLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.transfer_event", tusdAddr)).StructScan(&transferLog)
+ Expect(err).ToNot(HaveOccurred())
+ // We don't know vulcID, so compare individual fields instead of complete structures
+ Expect(transferLog.HeaderID).To(Equal(headerID))
+ Expect(transferLog.From).To(Equal("0x1062a747393198f70F71ec65A582423Dba7E5Ab3"))
+ Expect(transferLog.To).To(Equal("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0"))
+ Expect(transferLog.Value).To(Equal("9998940000000000000000"))
+ })
+
+ It("Keeps track of contract-related hashes and addresses while transforming event data if they need to be used for later method polling", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ ens, ok := t.Contracts[ensAddr]
+ Expect(ok).To(Equal(true))
+ tusd, ok := t.Contracts[tusdAddr]
+ Expect(ok).To(Equal(true))
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(ens.EmittedHashes)).To(Equal(2))
+ Expect(len(ens.EmittedAddrs)).To(Equal(0))
+ Expect(len(tusd.EmittedAddrs)).To(Equal(4))
+ Expect(len(tusd.EmittedHashes)).To(Equal(0))
+
+ b, ok := ens.EmittedHashes[common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = ens.EmittedHashes[common.HexToHash("0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = tusd.EmittedAddrs[common.HexToAddress("0x1062a747393198f70F71ec65A582423Dba7E5Ab3")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = tusd.EmittedAddrs[common.HexToAddress("0x2930096dB16b4A44Ecd4084EA4bd26F7EeF1AEf0")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = tusd.EmittedAddrs[common.HexToAddress("0x571A326f5B15E16917dC17761c340c1ec5d06f6d")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = tusd.EmittedAddrs[common.HexToAddress("0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+ })
+
+ It("Polls given methods for each contract, using list of collected values", func() {
+ t := transformer.NewTransformer("", blockChain, db)
+ t.SetEvents(constants.EnsContractAddress, []string{"NewOwner"})
+ t.SetMethods(constants.EnsContractAddress, []string{"owner"})
+ t.SetEvents(constants.TusdContractAddress, []string{"Transfer"})
+ t.SetMethods(constants.TusdContractAddress, []string{"balanceOf"})
+ err = t.Init()
+ Expect(err).ToNot(HaveOccurred())
+ err = t.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ owner := test_helpers.Owner{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885696'", ensAddr)).StructScan(&owner)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(owner.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef"))
+ Expect(owner.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ce695797aaf402b1c186bad9eca28842625b5047' AND block = '6885696'", ensAddr)).StructScan(&owner)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(owner.Address).To(Equal("0x0000000000000000000000000000000000000000"))
+ Expect(owner.TokenName).To(Equal(""))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHIS288IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&owner)
+ Expect(err).To(HaveOccurred())
+
+ bal := test_helpers.BalanceOf{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x1062a747393198f70F71ec65A582423Dba7E5Ab3' AND block = '6791669'", tusdAddr)).StructScan(&bal)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(bal.Balance).To(Equal("55849938025000000000000"))
+ Expect(bal.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x09BbBBE21a5975cAc061D82f7b843b1234567890' AND block = '6791669'", tusdAddr)).StructScan(&bal)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+})
diff --git a/pkg/omni/shared/constants/constants.go b/pkg/omni/shared/constants/constants.go
new file mode 100644
index 00000000..594e0fce
--- /dev/null
+++ b/pkg/omni/shared/constants/constants.go
@@ -0,0 +1,127 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package constants
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/filters"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers"
+)
+
+// Event enums
+type Event int
+
+const (
+ TransferEvent Event = 0
+ ApprovalEvent Event = 1
+ BurnEvent Event = 2
+ MintEvent Event = 3
+ NewOwnerEvent Event = 4
+)
+
+func (e Event) String() string {
+ strings := [...]string{
+ "Transfer",
+ "Approval",
+ "Burn",
+ "Mint",
+ "NewOwner",
+ }
+
+ if e < TransferEvent || e > NewOwnerEvent {
+ return "Unknown"
+ }
+
+ return strings[e]
+}
+
+func (e Event) Signature() string {
+ strings := [...]string{
+ helpers.GenerateSignature("Transfer(address,address,uint256)"),
+ helpers.GenerateSignature("Approval(address,address,uint256)"),
+ helpers.GenerateSignature("Burn(address,uint256)"),
+ helpers.GenerateSignature("Mint(address,uint256)"),
+ helpers.GenerateSignature("NewOwner(bytes32,bytes32,address)"),
+ }
+
+ if e < TransferEvent || e > NewOwnerEvent {
+ return "Unknown"
+ }
+
+ return strings[e]
+}
+
+// Contract Addresses
+var DaiContractAddress = "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+var TusdContractAddress = "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E"
+var EnsContractAddress = "0x314159265dD8dbb310642f98f50C066173C1259b"
+var PublicResolverAddress = "0x1da022710dF5002339274AaDEe8D58218e9D6AB5"
+
+// Contract Owner
+var DaiContractOwner = "0x0000000000000000000000000000000000000000"
+var TusdContractOwner = "0x9978d2d229a69b3aef93420d132ab22b44e3578f"
+
+// Contract Abis
+var DaiAbiString = `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name_","type":"bytes32"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"push","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"move","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint256"}],"name":"pull","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"symbol_","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"}]`
+
+var TusdAbiString = `[{"constant":true,"inputs":[],"name":"burnMin","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"delegateAllowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"burnFeeFlat","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_canReceiveMintWhiteList","type":"address"},{"name":"_canBurnWhiteList","type":"address"},{"name":"_blackList","type":"address"},{"name":"_noFeesList","type":"address"}],"name":"setLists","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"reclaimToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newContract","type":"address"}],"name":"delegateToNewContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_transferFeeNumerator","type":"uint80"},{"name":"_transferFeeDenominator","type":"uint80"},{"name":"_mintFeeNumerator","type":"uint80"},{"name":"_mintFeeDenominator","type":"uint80"},{"name":"_mintFeeFlat","type":"uint256"},{"name":"_burnFeeNumerator","type":"uint80"},{"name":"_burnFeeDenominator","type":"uint80"},{"name":"_burnFeeFlat","type":"uint256"}],"name":"changeStakingFees","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"canReceiveMintWhiteList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"delegatedFrom","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateApprove","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"contractAddr","type":"address"}],"name":"reclaimContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"allowances","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"delegateBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateTransferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sheet","type":"address"}],"name":"setBalanceSheet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateIncreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"burnFeeNumerator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"canBurnWhiteList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"burnMax","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mintFeeDenominator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"staker","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"setDelegatedFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"noFeesList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newMin","type":"uint256"},{"name":"newMax","type":"uint256"}],"name":"changeBurnBounds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"delegateTotalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"balances","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"}],"name":"changeName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"mintFeeNumerator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"transferFeeNumerator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateDecreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateTransfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"reclaimEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newStaker","type":"address"}],"name":"changeStaker","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"wipeBlacklistedAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from_","type":"address"},{"name":"value_","type":"uint256"},{"name":"data_","type":"bytes"}],"name":"tokenFallback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"burnFeeDenominator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"delegate","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"blackList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"transferFeeDenominator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mintFeeFlat","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sheet","type":"address"}],"name":"setAllowanceSheet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newMin","type":"uint256"},{"indexed":false,"name":"newMax","type":"uint256"}],"name":"ChangeBurnBoundsEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"balance","type":"uint256"}],"name":"WipedAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"newContract","type":"address"}],"name":"DelegatedTo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`
+
+var ENSAbiString = `[{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"label","type":"bytes32"},{"name":"owner","type":"address"}],"name":"setSubnodeOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"ttl","type":"uint64"}],"name":"setTTL","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"node","type":"bytes32"}],"name":"ttl","outputs":[{"name":"","type":"uint64"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"node","type":"bytes32"},{"name":"owner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"owner","type":"address"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":true,"name":"label","type":"bytes32"},{"indexed":false,"name":"owner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"resolver","type":"address"}],"name":"NewResolver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"ttl","type":"uint64"}],"name":"NewTTL","type":"event"}]`
+
+// Look-up table for ABI strings
+var Abis = map[common.Address]string{
+ common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b"): ENSAbiString,
+ common.HexToAddress("0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E"): TusdAbiString,
+ common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"): DaiAbiString,
+}
+
+// Filters
+// To add additional filter parameters, filter by other Topics e.g. for a Transfer event filter Topics[1] to filter for a specific 'from' address
+var DaiERC20Filters = []filters.LogFilter{
+ {
+ Name: TransferEvent.String(),
+ FromBlock: 4752008,
+ ToBlock: -1,
+ Address: DaiContractAddress,
+ Topics: core.Topics{TransferEvent.Signature()},
+ },
+ {
+ Name: ApprovalEvent.String(),
+ FromBlock: 4752008,
+ ToBlock: -1,
+ Address: DaiContractAddress,
+ Topics: core.Topics{ApprovalEvent.Signature()},
+ },
+}
+
+var TusdGenericFilters = []filters.LogFilter{
+ {
+ Name: BurnEvent.String(),
+ FromBlock: 5197514,
+ ToBlock: -1,
+ Address: TusdContractAddress,
+ Topics: core.Topics{BurnEvent.Signature()},
+ },
+ {
+ Name: MintEvent.String(),
+ FromBlock: 5197514,
+ ToBlock: -1,
+ Address: TusdContractAddress,
+ Topics: core.Topics{MintEvent.Signature()},
+ },
+}
diff --git a/pkg/omni/shared/constants/interface.go b/pkg/omni/shared/constants/interface.go
new file mode 100644
index 00000000..a1bf56b0
--- /dev/null
+++ b/pkg/omni/shared/constants/interface.go
@@ -0,0 +1,127 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package constants
+
+import (
+ "github.com/ethereum/go-ethereum/common/hexutil"
+)
+
+// Basic abi needed to check which interfaces are adhered to
+var SupportsInterfaceABI = `[{"constant":true,"inputs":[{"name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}]`
+
+// Individual event interfaces for constructing ABI from
+var SupportsInterace = `{"constant":true,"inputs":[{"name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}`
+var AddrChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"a","type":"address"}],"name":"AddrChanged","type":"event"}`
+var ContentChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"hash","type":"bytes32"}],"name":"ContentChanged","type":"event"}`
+var NameChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"name","type":"string"}],"name":"NameChanged","type":"event"}`
+var AbiChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":true,"name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"}`
+var PubkeyChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"x","type":"bytes32"},{"indexed":false,"name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"}`
+var TextChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"indexedKey","type":"string"},{"indexed":false,"name":"key","type":"string"}],"name":"TextChanged","type":"event"}`
+var MultihashChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"hash","type":"bytes"}],"name":"MultihashChanged","type":"event"}`
+var ContenthashChangeInterface = `{"anonymous":false,"inputs":[{"indexed":true,"name":"node","type":"bytes32"},{"indexed":false,"name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"}`
+
+var StartingBlock = int64(3648359)
+
+// Resolver interface signatures
+type Interface int
+
+const (
+ MetaSig Interface = iota
+ AddrChangeSig
+ ContentChangeSig
+ NameChangeSig
+ AbiChangeSig
+ PubkeyChangeSig
+ TextChangeSig
+ MultihashChangeSig
+ ContentHashChangeSig
+)
+
+func (e Interface) Hex() string {
+ strings := [...]string{
+ "0x01ffc9a7",
+ "0x3b3b57de",
+ "0xd8389dc5",
+ "0x691f3431",
+ "0x2203ab56",
+ "0xc8690233",
+ "0x59d1d43c",
+ "0xe89401a1",
+ "0xbc1c58d1",
+ }
+
+ if e < MetaSig || e > ContentHashChangeSig {
+ return "Unknown"
+ }
+
+ return strings[e]
+}
+
+func (e Interface) Bytes() [4]uint8 {
+ if e < MetaSig || e > ContentHashChangeSig {
+ return [4]byte{}
+ }
+
+ str := e.Hex()
+ by, _ := hexutil.Decode(str)
+ var byArray [4]uint8
+ for i := 0; i < 4; i++ {
+ byArray[i] = by[i]
+ }
+
+ return byArray
+}
+
+func (e Interface) EventSig() string {
+ strings := [...]string{
+ "",
+ "AddrChanged(bytes32,address)",
+ "ContentChanged(bytes32,bytes32)",
+ "NameChanged(bytes32,string)",
+ "ABIChanged(bytes32,uint256)",
+ "PubkeyChanged(bytes32,bytes32,bytes32)",
+ "TextChanged(bytes32,string,string)",
+ "MultihashChanged(bytes32,bytes)",
+ "ContenthashChanged(bytes32,bytes)",
+ }
+
+ if e < MetaSig || e > ContentHashChangeSig {
+ return "Unknown"
+ }
+
+ return strings[e]
+}
+
+func (e Interface) MethodSig() string {
+ strings := [...]string{
+ "supportsInterface(bytes4)",
+ "addr(bytes32)",
+ "content(bytes32)",
+ "name(bytes32)",
+ "ABI(bytes32,uint256)",
+ "pubkey(bytes32)",
+ "text(bytes32,string)",
+ "multihash(bytes32)",
+ "setContenthash(bytes32,bytes)",
+ }
+
+ if e < MetaSig || e > ContentHashChangeSig {
+ return "Unknown"
+ }
+
+ return strings[e]
+}
diff --git a/pkg/omni/shared/contract/contract.go b/pkg/omni/shared/contract/contract.go
new file mode 100644
index 00000000..a916e734
--- /dev/null
+++ b/pkg/omni/shared/contract/contract.go
@@ -0,0 +1,176 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package contract
+
+import (
+ "errors"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/filters"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+// Contract object to hold our contract data
+type Contract struct {
+ Name string // Name of the contract
+ Address string // Address of the contract
+ Network string // Network on which the contract is deployed; default empty "" is Ethereum mainnet
+ StartingBlock int64 // Starting block of the contract
+ LastBlock int64 // Most recent block on the network
+ Abi string // Abi string
+ ParsedAbi abi.ABI // Parsed abi
+ Events map[string]types.Event // List of events to watch
+ Methods []types.Method // List of methods to poll
+ Filters map[string]filters.LogFilter // Map of event filters to their event names; used only for full sync watcher
+ FilterArgs map[string]bool // User-input list of values to filter event logs for
+ MethodArgs map[string]bool // User-input list of values to limit method polling to
+ EmittedAddrs map[interface{}]bool // List of all unique addresses collected from converted event logs
+ EmittedHashes map[interface{}]bool // List of all unique hashes collected from converted event logs
+ CreateAddrList bool // Whether or not to persist address list to postgres
+ CreateHashList bool // Whether or not to persist hash list to postgres
+ Piping bool // Whether or not to pipe method results forward as arguments to subsequent methods
+}
+
+// If we will be calling methods that use addr, hash, or byte arrays
+// as arguments then we initialize maps to hold these types of values
+func (c Contract) Init() *Contract {
+ for _, method := range c.Methods {
+ for _, arg := range method.Args {
+ switch arg.Type.T {
+ case abi.AddressTy:
+ c.EmittedAddrs = map[interface{}]bool{}
+ case abi.HashTy, abi.BytesTy, abi.FixedBytesTy:
+ c.EmittedHashes = map[interface{}]bool{}
+ default:
+ }
+ }
+ }
+
+ // If we are creating an address list in postgres
+ // we initialize the map despite what method call, if any
+ if c.CreateAddrList {
+ c.EmittedAddrs = map[interface{}]bool{}
+ }
+
+ return &c
+}
+
+// Use contract info to generate event filters - full sync omni watcher only
+func (c *Contract) GenerateFilters() error {
+ c.Filters = map[string]filters.LogFilter{}
+
+ for name, event := range c.Events {
+ c.Filters[name] = filters.LogFilter{
+ Name: event.Name,
+ FromBlock: c.StartingBlock,
+ ToBlock: -1,
+ Address: common.HexToAddress(c.Address).Hex(),
+ Topics: core.Topics{event.Sig().Hex()},
+ }
+ }
+ // If no filters were generated, throw an error (no point in continuing with this contract)
+ if len(c.Filters) == 0 {
+ return errors.New("error: no filters created")
+ }
+
+ return nil
+}
+
+// Returns true if address is in list of arguments to
+// filter events for or if no filtering is specified
+func (c *Contract) WantedEventArg(arg string) bool {
+ if c.FilterArgs == nil {
+ return false
+ } else if len(c.FilterArgs) == 0 {
+ return true
+ } else if a, ok := c.FilterArgs[arg]; ok {
+ return a
+ }
+
+ return false
+}
+
+// Returns true if address is in list of arguments to
+// poll methods with or if no filtering is specified
+func (c *Contract) WantedMethodArg(arg interface{}) bool {
+ if c.MethodArgs == nil {
+ return false
+ } else if len(c.MethodArgs) == 0 {
+ return true
+ }
+
+ // resolve interface to one of the three types we handle as arguments
+ str := StringifyArg(arg)
+
+ // See if it's hex string has been filtered for
+ if a, ok := c.MethodArgs[str]; ok {
+ return a
+ }
+
+ return false
+}
+
+// Returns true if any mapping value matches filtered for address or if no filter exists
+// Used to check if an event log name-value mapping should be filtered or not
+func (c *Contract) PassesEventFilter(args map[string]string) bool {
+ for _, arg := range args {
+ if c.WantedEventArg(arg) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Add event emitted address to our list if it passes filter and method polling is on
+func (c *Contract) AddEmittedAddr(addresses ...interface{}) {
+ for _, addr := range addresses {
+ if c.WantedMethodArg(addr) && c.Methods != nil {
+ c.EmittedAddrs[addr] = true
+ }
+ }
+}
+
+// Add event emitted hash to our list if it passes filter and method polling is on
+func (c *Contract) AddEmittedHash(hashes ...interface{}) {
+ for _, hash := range hashes {
+ if c.WantedMethodArg(hash) && c.Methods != nil {
+ c.EmittedHashes[hash] = true
+ }
+ }
+}
+
+func StringifyArg(arg interface{}) (str string) {
+ switch arg.(type) {
+ case string:
+ str = arg.(string)
+ case common.Address:
+ a := arg.(common.Address)
+ str = a.String()
+ case common.Hash:
+ a := arg.(common.Hash)
+ str = a.String()
+ case []byte:
+ a := arg.([]byte)
+ str = hexutil.Encode(a)
+ }
+
+ return
+}
diff --git a/pkg/omni/shared/contract/contract_suite_test.go b/pkg/omni/shared/contract/contract_suite_test.go
new file mode 100644
index 00000000..9ef74e40
--- /dev/null
+++ b/pkg/omni/shared/contract/contract_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package contract_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestContract(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Contract Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/shared/contract/contract_test.go b/pkg/omni/shared/contract/contract_test.go
new file mode 100644
index 00000000..a9164f94
--- /dev/null
+++ b/pkg/omni/shared/contract/contract_test.go
@@ -0,0 +1,236 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package contract_test
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+var _ = Describe("Contract", func() {
+ var err error
+ var info *contract.Contract
+ var wantedEvents = []string{"Transfer", "Approval"}
+
+ Describe("GenerateFilters", func() {
+
+ It("Generates filters from contract data", func() {
+ info = test_helpers.SetupTusdContract(wantedEvents, nil)
+ err = info.GenerateFilters()
+ Expect(err).ToNot(HaveOccurred())
+
+ val, ok := info.Filters["Transfer"]
+ Expect(ok).To(Equal(true))
+ Expect(val).To(Equal(mocks.ExpectedTransferFilter))
+
+ val, ok = info.Filters["Approval"]
+ Expect(ok).To(Equal(true))
+ Expect(val).To(Equal(mocks.ExpectedApprovalFilter))
+
+ val, ok = info.Filters["Mint"]
+ Expect(ok).To(Equal(false))
+
+ })
+
+ It("Fails with an empty contract", func() {
+ info = &contract.Contract{}
+ err = info.GenerateFilters()
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("IsEventAddr", func() {
+
+ BeforeEach(func() {
+ info = &contract.Contract{}
+ info.MethodArgs = map[string]bool{}
+ info.FilterArgs = map[string]bool{}
+ })
+
+ It("Returns true if address is in event address filter list", func() {
+ info.FilterArgs["testAddress1"] = true
+ info.FilterArgs["testAddress2"] = true
+
+ is := info.WantedEventArg("testAddress1")
+ Expect(is).To(Equal(true))
+ is = info.WantedEventArg("testAddress2")
+ Expect(is).To(Equal(true))
+
+ info.MethodArgs["testAddress3"] = true
+ is = info.WantedEventArg("testAddress3")
+ Expect(is).To(Equal(false))
+ })
+
+ It("Returns true if event address filter is empty (no filter)", func() {
+ is := info.WantedEventArg("testAddress1")
+ Expect(is).To(Equal(true))
+ is = info.WantedEventArg("testAddress2")
+ Expect(is).To(Equal(true))
+ })
+
+ It("Returns false if address is not in event address filter list", func() {
+ info.FilterArgs["testAddress1"] = true
+ info.FilterArgs["testAddress2"] = true
+
+ is := info.WantedEventArg("testAddress3")
+ Expect(is).To(Equal(false))
+ })
+
+ It("Returns false if event address filter is nil (block all)", func() {
+ info.FilterArgs = nil
+
+ is := info.WantedEventArg("testAddress1")
+ Expect(is).To(Equal(false))
+ is = info.WantedEventArg("testAddress2")
+ Expect(is).To(Equal(false))
+ })
+ })
+
+ Describe("IsMethodAddr", func() {
+ BeforeEach(func() {
+ info = &contract.Contract{}
+ info.MethodArgs = map[string]bool{}
+ info.FilterArgs = map[string]bool{}
+ })
+
+ It("Returns true if address is in method address filter list", func() {
+ info.MethodArgs["testAddress1"] = true
+ info.MethodArgs["testAddress2"] = true
+
+ is := info.WantedMethodArg("testAddress1")
+ Expect(is).To(Equal(true))
+ is = info.WantedMethodArg("testAddress2")
+ Expect(is).To(Equal(true))
+
+ info.FilterArgs["testAddress3"] = true
+ is = info.WantedMethodArg("testAddress3")
+ Expect(is).To(Equal(false))
+ })
+
+ It("Returns true if method address filter list is empty (no filter)", func() {
+ is := info.WantedMethodArg("testAddress1")
+ Expect(is).To(Equal(true))
+ is = info.WantedMethodArg("testAddress2")
+ Expect(is).To(Equal(true))
+ })
+
+ It("Returns false if address is not in method address filter list", func() {
+ info.MethodArgs["testAddress1"] = true
+ info.MethodArgs["testAddress2"] = true
+
+ is := info.WantedMethodArg("testAddress3")
+ Expect(is).To(Equal(false))
+ })
+
+ It("Returns false if method address filter list is nil (block all)", func() {
+ info.MethodArgs = nil
+
+ is := info.WantedMethodArg("testAddress1")
+ Expect(is).To(Equal(false))
+ is = info.WantedMethodArg("testAddress2")
+ Expect(is).To(Equal(false))
+ })
+ })
+
+ Describe("PassesEventFilter", func() {
+ var mapping map[string]string
+ BeforeEach(func() {
+ info = &contract.Contract{}
+ info.FilterArgs = map[string]bool{}
+ mapping = map[string]string{}
+
+ })
+
+ It("Return true if event log name-value mapping has filtered for address as a value", func() {
+ info.FilterArgs["testAddress1"] = true
+ info.FilterArgs["testAddress2"] = true
+
+ mapping["testInputName1"] = "testAddress1"
+ mapping["testInputName2"] = "testAddress2"
+ mapping["testInputName3"] = "testAddress3"
+
+ pass := info.PassesEventFilter(mapping)
+ Expect(pass).To(Equal(true))
+ })
+
+ It("Return true if event address filter list is empty (no filter)", func() {
+ mapping["testInputName1"] = "testAddress1"
+ mapping["testInputName2"] = "testAddress2"
+ mapping["testInputName3"] = "testAddress3"
+
+ pass := info.PassesEventFilter(mapping)
+ Expect(pass).To(Equal(true))
+ })
+
+ It("Return false if event log name-value mapping does not have filtered for address as a value", func() {
+ info.FilterArgs["testAddress1"] = true
+ info.FilterArgs["testAddress2"] = true
+
+ mapping["testInputName3"] = "testAddress3"
+
+ pass := info.PassesEventFilter(mapping)
+ Expect(pass).To(Equal(false))
+ })
+
+ It("Return false if event address filter list is nil (block all)", func() {
+ info.FilterArgs = nil
+
+ mapping["testInputName1"] = "testAddress1"
+ mapping["testInputName2"] = "testAddress2"
+ mapping["testInputName3"] = "testAddress3"
+
+ pass := info.PassesEventFilter(mapping)
+ Expect(pass).To(Equal(false))
+ })
+ })
+
+ Describe("AddEmittedAddr", func() {
+ BeforeEach(func() {
+ info = &contract.Contract{}
+ info.FilterArgs = map[string]bool{}
+ info.MethodArgs = map[string]bool{}
+ info.Methods = []types.Method{}
+ info.EmittedAddrs = map[interface{}]bool{}
+ })
+
+ It("Adds address to list if it is on the method filter address list", func() {
+ info.MethodArgs["testAddress2"] = true
+ info.AddEmittedAddr("testAddress2")
+ b := info.EmittedAddrs["testAddress2"]
+ Expect(b).To(Equal(true))
+ })
+
+ It("Adds address to list if method filter is empty", func() {
+ info.AddEmittedAddr("testAddress2")
+ b := info.EmittedAddrs["testAddress2"]
+ Expect(b).To(Equal(true))
+ })
+
+ It("Does not add address to list if both filters are closed (nil)", func() {
+ info.FilterArgs = nil // close both
+ info.MethodArgs = nil
+ info.AddEmittedAddr("testAddress1")
+ b := info.EmittedAddrs["testAddress1"]
+ Expect(b).To(Equal(false))
+ })
+ })
+})
diff --git a/pkg/omni/shared/fetcher/fetcher.go b/pkg/omni/shared/fetcher/fetcher.go
new file mode 100644
index 00000000..0f5d5459
--- /dev/null
+++ b/pkg/omni/shared/fetcher/fetcher.go
@@ -0,0 +1,124 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package fetcher
+
+import (
+ "fmt"
+ "log"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+)
+
+// Fetcher serves as the lower level data fetcher that calls the underlying
+// blockchain's FetchConctractData method for a given return type
+
+// Interface definition for a Fetcher
+type FetcherInterface interface {
+ FetchBigInt(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error)
+ FetchBool(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (bool, error)
+ FetchAddress(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Address, error)
+ FetchString(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (string, error)
+ FetchHash(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Hash, error)
+}
+
+// Used to create a new Fetcher error for a given error and fetch method
+func newFetcherError(err error, fetchMethod string) *fetcherError {
+ e := fetcherError{err.Error(), fetchMethod}
+ log.Println(e.Error())
+ return &e
+}
+
+// Fetcher struct
+type Fetcher struct {
+ BlockChain core.BlockChain // Underyling Blockchain
+}
+
+// Fetcher error
+type fetcherError struct {
+ err string
+ fetchMethod string
+}
+
+// Fetcher error method
+func (fe *fetcherError) Error() string {
+ return fmt.Sprintf("Error fetching %s: %s", fe.fetchMethod, fe.err)
+}
+
+// Generic Fetcher methods used by Getters to call contract methods
+
+// Method used to fetch big.Int value from contract
+func (f Fetcher) FetchBigInt(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (big.Int, error) {
+ var result = new(big.Int)
+ err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
+
+ if err != nil {
+ return *result, newFetcherError(err, method)
+ }
+
+ return *result, nil
+}
+
+// Method used to fetch bool value from contract
+func (f Fetcher) FetchBool(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (bool, error) {
+ var result = new(bool)
+ err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
+
+ if err != nil {
+ return *result, newFetcherError(err, method)
+ }
+
+ return *result, nil
+}
+
+// Method used to fetch address value from contract
+func (f Fetcher) FetchAddress(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Address, error) {
+ var result = new(common.Address)
+ err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
+
+ if err != nil {
+ return *result, newFetcherError(err, method)
+ }
+
+ return *result, nil
+}
+
+// Method used to fetch string value from contract
+func (f Fetcher) FetchString(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (string, error) {
+ var result = new(string)
+ err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
+
+ if err != nil {
+ return *result, newFetcherError(err, method)
+ }
+
+ return *result, nil
+}
+
+// Method used to fetch hash value from contract
+func (f Fetcher) FetchHash(method, contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (common.Hash, error) {
+ var result = new(common.Hash)
+ err := f.BlockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
+
+ if err != nil {
+ return *result, newFetcherError(err, method)
+ }
+
+ return *result, nil
+}
diff --git a/pkg/omni/shared/getter/getter_suite_test.go b/pkg/omni/shared/getter/getter_suite_test.go
new file mode 100644
index 00000000..78fdc7bf
--- /dev/null
+++ b/pkg/omni/shared/getter/getter_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package getter_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestRepository(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Getter Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/shared/getter/getter_test.go b/pkg/omni/shared/getter/getter_test.go
new file mode 100644
index 00000000..1c440972
--- /dev/null
+++ b/pkg/omni/shared/getter/getter_test.go
@@ -0,0 +1,55 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package getter_test
+
+import (
+ "github.com/ethereum/go-ethereum/ethclient"
+ "github.com/ethereum/go-ethereum/rpc"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/geth"
+ "github.com/vulcanize/vulcanizedb/pkg/geth/client"
+ rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
+ "github.com/vulcanize/vulcanizedb/pkg/geth/node"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/getter"
+)
+
+var _ = Describe("Interface Getter", func() {
+ Describe("GetAbi", func() {
+ It("Constructs and returns a custom abi based on results from supportsInterface calls", func() {
+ expectedABI := `[` + constants.AddrChangeInterface + `,` + constants.NameChangeInterface + `,` + constants.ContentChangeInterface + `,` + constants.AbiChangeInterface + `,` + constants.PubkeyChangeInterface + `]`
+
+ blockNumber := int64(6885696)
+ infuraIPC := "https://mainnet.infura.io/v3/b09888c1113640cc9ab42750ce750c05"
+ rawRpcClient, err := rpc.Dial(infuraIPC)
+ Expect(err).NotTo(HaveOccurred())
+ rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
+ ethClient := ethclient.NewClient(rawRpcClient)
+ blockChainClient := client.NewEthClient(ethClient)
+ node := node.MakeNode(rpcClient)
+ transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
+ blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
+ interfaceGetter := getter.NewInterfaceGetter(blockChain)
+ abi := interfaceGetter.GetABI(constants.PublicResolverAddress, blockNumber)
+ Expect(abi).To(Equal(expectedABI))
+ _, err = geth.ParseAbi(abi)
+ Expect(err).ToNot(HaveOccurred())
+ })
+ })
+})
diff --git a/pkg/omni/shared/getter/interface_getter.go b/pkg/omni/shared/getter/interface_getter.go
new file mode 100644
index 00000000..a49ac669
--- /dev/null
+++ b/pkg/omni/shared/getter/interface_getter.go
@@ -0,0 +1,105 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package getter
+
+import (
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/fetcher"
+)
+
+type InterfaceGetter interface {
+ GetABI(resolverAddr string, blockNumber int64) string
+ GetBlockChain() core.BlockChain
+}
+
+type interfaceGetter struct {
+ fetcher.Fetcher
+}
+
+func NewInterfaceGetter(blockChain core.BlockChain) *interfaceGetter {
+ return &interfaceGetter{
+ Fetcher: fetcher.Fetcher{
+ BlockChain: blockChain,
+ },
+ }
+}
+
+// Used to construct a custom ABI based on the results from calling supportsInterface
+func (g *interfaceGetter) GetABI(resolverAddr string, blockNumber int64) string {
+ a := constants.SupportsInterfaceABI
+ args := make([]interface{}, 1)
+ args[0] = constants.MetaSig.Bytes()
+ supports, err := g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err != nil || !supports {
+ return ""
+ }
+ abiStr := `[`
+ args[0] = constants.AddrChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.AddrChangeInterface + ","
+ }
+ args[0] = constants.NameChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.NameChangeInterface + ","
+ }
+ args[0] = constants.ContentChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.ContentChangeInterface + ","
+ }
+ args[0] = constants.AbiChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.AbiChangeInterface + ","
+ }
+ args[0] = constants.PubkeyChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.PubkeyChangeInterface + ","
+ }
+ args[0] = constants.ContentHashChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.ContenthashChangeInterface + ","
+ }
+ args[0] = constants.MultihashChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.MultihashChangeInterface + ","
+ }
+ args[0] = constants.TextChangeSig.Bytes()
+ supports, err = g.getSupportsInterface(a, resolverAddr, blockNumber, args)
+ if err == nil && supports {
+ abiStr += constants.TextChangeInterface + ","
+ }
+ abiStr = abiStr[:len(abiStr)-1] + `]`
+
+ return abiStr
+}
+
+// Use this method to check whether or not a contract supports a given method/event interface
+func (g *interfaceGetter) getSupportsInterface(contractAbi, contractAddress string, blockNumber int64, methodArgs []interface{}) (bool, error) {
+ return g.Fetcher.FetchBool("supportsInterface", contractAbi, contractAddress, blockNumber, methodArgs)
+}
+
+// Method to retrieve the Getter's blockchain
+func (g *interfaceGetter) GetBlockChain() core.BlockChain {
+ return g.Fetcher.BlockChain
+}
diff --git a/pkg/omni/shared/helpers/helpers.go b/pkg/omni/shared/helpers/helpers.go
new file mode 100644
index 00000000..3c448989
--- /dev/null
+++ b/pkg/omni/shared/helpers/helpers.go
@@ -0,0 +1,69 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package helpers
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+)
+
+func ConvertToLog(watchedEvent core.WatchedEvent) types.Log {
+ allTopics := []string{watchedEvent.Topic0, watchedEvent.Topic1, watchedEvent.Topic2, watchedEvent.Topic3}
+ var nonNilTopics []string
+ for _, topic := range allTopics {
+ if topic != "" {
+ nonNilTopics = append(nonNilTopics, topic)
+ }
+ }
+ return types.Log{
+ Address: common.HexToAddress(watchedEvent.Address),
+ Topics: createTopics(nonNilTopics...),
+ Data: hexutil.MustDecode(watchedEvent.Data),
+ BlockNumber: uint64(watchedEvent.BlockNumber),
+ TxHash: common.HexToHash(watchedEvent.TxHash),
+ TxIndex: 0,
+ BlockHash: common.HexToHash("0x0"),
+ Index: uint(watchedEvent.Index),
+ Removed: false,
+ }
+}
+
+func createTopics(topics ...string) []common.Hash {
+ var topicsArray []common.Hash
+ for _, topic := range topics {
+ topicsArray = append(topicsArray, common.HexToHash(topic))
+ }
+ return topicsArray
+}
+
+func BigFromString(n string) *big.Int {
+ b := new(big.Int)
+ b.SetString(n, 10)
+ return b
+}
+
+func GenerateSignature(s string) string {
+ eventSignature := []byte(s)
+ hash := crypto.Keccak256Hash(eventSignature)
+ return hash.Hex()
+}
diff --git a/pkg/omni/shared/helpers/test_helpers/database.go b/pkg/omni/shared/helpers/test_helpers/database.go
new file mode 100644
index 00000000..c2f094d1
--- /dev/null
+++ b/pkg/omni/shared/helpers/test_helpers/database.go
@@ -0,0 +1,318 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package test_helpers
+
+import (
+ "math/rand"
+
+ "github.com/ethereum/go-ethereum/ethclient"
+ "github.com/ethereum/go-ethereum/rpc"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/config"
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/geth"
+ "github.com/vulcanize/vulcanizedb/pkg/geth/client"
+ rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
+ "github.com/vulcanize/vulcanizedb/pkg/geth/node"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+)
+
+type TransferLog struct {
+ Id int64 `db:"id"`
+ VulvanizeLogId int64 `db:"vulcanize_log_id"`
+ TokenName string `db:"token_name"`
+ Block int64 `db:"block"`
+ Tx string `db:"tx"`
+ From string `db:"from_"`
+ To string `db:"to_"`
+ Value string `db:"value_"`
+}
+
+type NewOwnerLog struct {
+ Id int64 `db:"id"`
+ VulvanizeLogId int64 `db:"vulcanize_log_id"`
+ TokenName string `db:"token_name"`
+ Block int64 `db:"block"`
+ Tx string `db:"tx"`
+ Node string `db:"node_"`
+ Label string `db:"label_"`
+ Owner string `db:"owner_"`
+}
+
+type LightTransferLog struct {
+ Id int64 `db:"id"`
+ HeaderID int64 `db:"header_id"`
+ TokenName string `db:"token_name"`
+ LogIndex int64 `db:"log_idx"`
+ TxIndex int64 `db:"tx_idx"`
+ From string `db:"from_"`
+ To string `db:"to_"`
+ Value string `db:"value_"`
+ RawLog []byte `db:"raw_log"`
+}
+
+type LightNewOwnerLog struct {
+ Id int64 `db:"id"`
+ HeaderID int64 `db:"header_id"`
+ TokenName string `db:"token_name"`
+ LogIndex int64 `db:"log_idx"`
+ TxIndex int64 `db:"tx_idx"`
+ Node string `db:"node_"`
+ Label string `db:"label_"`
+ Owner string `db:"owner_"`
+ RawLog []byte `db:"raw_log"`
+}
+
+type BalanceOf struct {
+ Id int64 `db:"id"`
+ TokenName string `db:"token_name"`
+ Block int64 `db:"block"`
+ Address string `db:"who_"`
+ Balance string `db:"returned"`
+}
+
+type Resolver struct {
+ Id int64 `db:"id"`
+ TokenName string `db:"token_name"`
+ Block int64 `db:"block"`
+ Node string `db:"node_"`
+ Address string `db:"returned"`
+}
+
+type Owner struct {
+ Id int64 `db:"id"`
+ TokenName string `db:"token_name"`
+ Block int64 `db:"block"`
+ Node string `db:"node_"`
+ Address string `db:"returned"`
+}
+
+func SetupBC() core.BlockChain {
+ infuraIPC := "https://mainnet.infura.io/v3/b09888c1113640cc9ab42750ce750c05"
+ rawRpcClient, err := rpc.Dial(infuraIPC)
+ Expect(err).NotTo(HaveOccurred())
+ rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
+ ethClient := ethclient.NewClient(rawRpcClient)
+ blockChainClient := client.NewEthClient(ethClient)
+ node := node.MakeNode(rpcClient)
+ transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
+ blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
+
+ return blockChain
+}
+
+func SetupDBandBC() (*postgres.DB, core.BlockChain) {
+ infuraIPC := "https://mainnet.infura.io/v3/b09888c1113640cc9ab42750ce750c05"
+ rawRpcClient, err := rpc.Dial(infuraIPC)
+ Expect(err).NotTo(HaveOccurred())
+ rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
+ ethClient := ethclient.NewClient(rawRpcClient)
+ blockChainClient := client.NewEthClient(ethClient)
+ node := node.MakeNode(rpcClient)
+ transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
+ blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
+
+ db, err := postgres.NewDB(config.Database{
+ Hostname: "localhost",
+ Name: "vulcanize_private",
+ Port: 5432,
+ }, blockChain.Node())
+ Expect(err).NotTo(HaveOccurred())
+
+ return db, blockChain
+}
+
+func SetupTusdRepo(vulcanizeLogId *int64, wantedEvents, wantedMethods []string) (*postgres.DB, *contract.Contract) {
+ db, err := postgres.NewDB(config.Database{
+ Hostname: "localhost",
+ Name: "vulcanize_private",
+ Port: 5432,
+ }, core.Node{})
+ Expect(err).NotTo(HaveOccurred())
+
+ receiptRepository := repositories.ReceiptRepository{DB: db}
+ logRepository := repositories.LogRepository{DB: db}
+ blockRepository := *repositories.NewBlockRepository(db)
+
+ blockNumber := rand.Int63()
+ blockId := CreateBlock(blockNumber, blockRepository)
+
+ receipts := []core.Receipt{{Logs: []core.Log{{}}}}
+
+ err = receiptRepository.CreateReceiptsAndLogs(blockId, receipts)
+ Expect(err).ToNot(HaveOccurred())
+
+ err = logRepository.Get(vulcanizeLogId, `SELECT id FROM logs`)
+ Expect(err).ToNot(HaveOccurred())
+
+ info := SetupTusdContract(wantedEvents, wantedMethods)
+
+ return db, info
+}
+
+func SetupTusdContract(wantedEvents, wantedMethods []string) *contract.Contract {
+ p := mocks.NewParser(constants.TusdAbiString)
+ err := p.Parse()
+ Expect(err).ToNot(HaveOccurred())
+
+ return contract.Contract{
+ Name: "TrueUSD",
+ Address: constants.TusdContractAddress,
+ Abi: p.Abi(),
+ ParsedAbi: p.ParsedAbi(),
+ StartingBlock: 6194634,
+ LastBlock: 6507323,
+ Events: p.GetEvents(wantedEvents),
+ Methods: p.GetSelectMethods(wantedMethods),
+ MethodArgs: map[string]bool{},
+ FilterArgs: map[string]bool{},
+ }.Init()
+}
+
+func SetupENSRepo(vulcanizeLogId *int64, wantedEvents, wantedMethods []string) (*postgres.DB, *contract.Contract) {
+ db, err := postgres.NewDB(config.Database{
+ Hostname: "localhost",
+ Name: "vulcanize_private",
+ Port: 5432,
+ }, core.Node{})
+ Expect(err).NotTo(HaveOccurred())
+
+ receiptRepository := repositories.ReceiptRepository{DB: db}
+ logRepository := repositories.LogRepository{DB: db}
+ blockRepository := *repositories.NewBlockRepository(db)
+
+ blockNumber := rand.Int63()
+ blockId := CreateBlock(blockNumber, blockRepository)
+
+ receipts := []core.Receipt{{Logs: []core.Log{{}}}}
+
+ err = receiptRepository.CreateReceiptsAndLogs(blockId, receipts)
+ Expect(err).ToNot(HaveOccurred())
+
+ err = logRepository.Get(vulcanizeLogId, `SELECT id FROM logs`)
+ Expect(err).ToNot(HaveOccurred())
+
+ info := SetupENSContract(wantedEvents, wantedMethods)
+
+ return db, info
+}
+
+func SetupENSContract(wantedEvents, wantedMethods []string) *contract.Contract {
+ p := mocks.NewParser(constants.ENSAbiString)
+ err := p.Parse()
+ Expect(err).ToNot(HaveOccurred())
+
+ return contract.Contract{
+ Name: "ENS-Registry",
+ Address: constants.EnsContractAddress,
+ Abi: p.Abi(),
+ ParsedAbi: p.ParsedAbi(),
+ StartingBlock: 6194634,
+ LastBlock: 6507323,
+ Events: p.GetEvents(wantedEvents),
+ Methods: p.GetSelectMethods(wantedMethods),
+ MethodArgs: map[string]bool{},
+ FilterArgs: map[string]bool{},
+ }.Init()
+}
+
+func TearDown(db *postgres.DB) {
+ tx, err := db.Begin()
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM blocks`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM headers`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM logs`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM log_filters`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM transactions`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM receipts`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DROP TABLE checked_headers`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`CREATE TABLE checked_headers (id SERIAL PRIMARY KEY, header_id INTEGER UNIQUE NOT NULL REFERENCES headers (id) ON DELETE CASCADE);`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`ALTER TABLE checked_headers
+ADD COLUMN IF NOT EXISTS price_feeds_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS flip_kick_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS frob_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS tend_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS bite_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS dent_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS pit_file_debt_ceiling_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS pit_file_ilk_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_init_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS drip_file_ilk_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS drip_file_repo_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS drip_file_vow_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS deal_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS drip_drip_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS cat_file_chop_lump_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS cat_file_flip_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS cat_file_pit_vow_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS flop_kick_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_move_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_fold_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_heal_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_toll_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_tune_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_grab_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_flux_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vat_slip_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS vow_flog_checked BOOLEAN NOT NULL DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS flap_kick_checked BOOLEAN NOT NULL DEFAULT FALSE`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DROP SCHEMA IF EXISTS full_0x8dd5fbce2f6a956c3022ba3663759011dd51e73e CASCADE`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DROP SCHEMA IF EXISTS light_0x8dd5fbce2f6a956c3022ba3663759011dd51e73e CASCADE`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DROP SCHEMA IF EXISTS full_0x314159265dd8dbb310642f98f50c066173c1259b CASCADE`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DROP SCHEMA IF EXISTS light_0x314159265dd8dbb310642f98f50c066173c1259b CASCADE`)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = tx.Commit()
+ Expect(err).NotTo(HaveOccurred())
+}
+
+func CreateBlock(blockNumber int64, repository repositories.BlockRepository) (blockId int64) {
+ blockId, err := repository.CreateOrUpdateBlock(core.Block{Number: blockNumber})
+ Expect(err).NotTo(HaveOccurred())
+
+ return blockId
+}
diff --git a/pkg/omni/shared/helpers/test_helpers/mocks/entities.go b/pkg/omni/shared/helpers/test_helpers/mocks/entities.go
new file mode 100644
index 00000000..4d865382
--- /dev/null
+++ b/pkg/omni/shared/helpers/test_helpers/mocks/entities.go
@@ -0,0 +1,251 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package mocks
+
+import (
+ "encoding/json"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/core/types"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/filters"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+)
+
+var TransferBlock1 = core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ert",
+ Number: 6194633,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654aaa",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654aaa",
+ ContractAddress: "",
+ Logs: []core.Log{{
+ BlockNumber: 6194633,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654aaa",
+ Address: constants.TusdContractAddress,
+ Topics: core.Topics{
+ constants.TransferEvent.Signature(),
+ "0x000000000000000000000000000000000000000000000000000000000000af21",
+ "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ "",
+ },
+ Index: 1,
+ Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
+ }},
+ },
+ }},
+}
+
+var TransferBlock2 = core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ooo",
+ Number: 6194634,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654eee",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654eee",
+ ContractAddress: "",
+ Logs: []core.Log{{
+ BlockNumber: 6194634,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654eee",
+ Address: constants.TusdContractAddress,
+ Topics: core.Topics{
+ constants.TransferEvent.Signature(),
+ "0x000000000000000000000000000000000000000000000000000000000000af21",
+ "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ "",
+ },
+ Index: 1,
+ Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
+ }},
+ },
+ }},
+}
+
+var NewOwnerBlock1 = core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ppp",
+ Number: 6194635,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654bbb",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654bbb",
+ ContractAddress: "",
+ Logs: []core.Log{{
+ BlockNumber: 6194635,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654bbb",
+ Address: constants.EnsContractAddress,
+ Topics: core.Topics{
+ constants.NewOwnerEvent.Signature(),
+ "0x0000000000000000000000000000000000000000000000000000c02aaa39b223",
+ "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ "",
+ },
+ Index: 1,
+ Data: "0x000000000000000000000000000000000000000000000000000000000000af21",
+ }},
+ },
+ }},
+}
+
+var NewOwnerBlock2 = core.Block{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ggg",
+ Number: 6194636,
+ Transactions: []core.Transaction{{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654lll",
+ Receipt: core.Receipt{
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654lll",
+ ContractAddress: "",
+ Logs: []core.Log{{
+ BlockNumber: 6194636,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad654lll",
+ Address: constants.EnsContractAddress,
+ Topics: core.Topics{
+ constants.NewOwnerEvent.Signature(),
+ "0x0000000000000000000000000000000000000000000000000000c02aaa39b223",
+ "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba400",
+ "",
+ },
+ Index: 1,
+ Data: "0x000000000000000000000000000000000000000000000000000000000000af21",
+ }},
+ },
+ }},
+}
+
+var ExpectedTransferFilter = filters.LogFilter{
+ Name: "Transfer",
+ Address: constants.TusdContractAddress,
+ ToBlock: -1,
+ FromBlock: 6194634,
+ Topics: core.Topics{constants.TransferEvent.Signature()},
+}
+
+var ExpectedApprovalFilter = filters.LogFilter{
+ Name: "Approval",
+ Address: constants.TusdContractAddress,
+ ToBlock: -1,
+ FromBlock: 6194634,
+ Topics: core.Topics{constants.ApprovalEvent.Signature()},
+}
+
+var MockTranferEvent = core.WatchedEvent{
+ LogID: 1,
+ Name: constants.TransferEvent.String(),
+ BlockNumber: 5488076,
+ Address: constants.TusdContractAddress,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ Index: 110,
+ Topic0: constants.TransferEvent.Signature(),
+ Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
+ Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ Topic3: "",
+ Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
+}
+
+var rawFakeHeader, _ = json.Marshal(core.Header{})
+
+var MockHeader1 = core.Header{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad123ert",
+ BlockNumber: 6194632,
+ Raw: rawFakeHeader,
+ Timestamp: "50000000",
+}
+
+var MockHeader2 = core.Header{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad456yui",
+ BlockNumber: 6194633,
+ Raw: rawFakeHeader,
+ Timestamp: "50000015",
+}
+
+var MockHeader3 = core.Header{
+ Hash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad234hfs",
+ BlockNumber: 6194634,
+ Raw: rawFakeHeader,
+ Timestamp: "50000030",
+}
+
+var MockTransferLog1 = types.Log{
+ Index: 1,
+ Address: common.HexToAddress(constants.TusdContractAddress),
+ BlockNumber: 5488076,
+ TxIndex: 110,
+ TxHash: common.HexToHash("0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae"),
+ Topics: []common.Hash{
+ common.HexToHash(constants.TransferEvent.Signature()),
+ common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000af21"),
+ common.HexToHash("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391"),
+ },
+ Data: hexutil.MustDecode("0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe"),
+}
+
+var MockTransferLog2 = types.Log{
+ Index: 3,
+ Address: common.HexToAddress(constants.TusdContractAddress),
+ BlockNumber: 5488077,
+ TxIndex: 2,
+ TxHash: common.HexToHash("0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546df"),
+ Topics: []common.Hash{
+ common.HexToHash(constants.TransferEvent.Signature()),
+ common.HexToHash("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391"),
+ common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000af21"),
+ },
+ Data: hexutil.MustDecode("0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe"),
+}
+
+var MockMintLog = types.Log{
+ Index: 10,
+ Address: common.HexToAddress(constants.TusdContractAddress),
+ BlockNumber: 5488080,
+ TxIndex: 50,
+ TxHash: common.HexToHash("0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6minty"),
+ Topics: []common.Hash{
+ common.HexToHash(constants.MintEvent.Signature()),
+ common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000af21"),
+ },
+ Data: hexutil.MustDecode("0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe"),
+}
+
+var MockNewOwnerLog1 = types.Log{
+ Index: 1,
+ Address: common.HexToAddress(constants.EnsContractAddress),
+ BlockNumber: 5488076,
+ TxIndex: 110,
+ TxHash: common.HexToHash("0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae"),
+ Topics: []common.Hash{
+ common.HexToHash(constants.NewOwnerEvent.Signature()),
+ common.HexToHash("0x000000000000000000000000c02aaa39b223helloa0e5c4f27ead9083c752553"),
+ common.HexToHash("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391"),
+ },
+ Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000000000000000af21"),
+}
+
+var MockNewOwnerLog2 = types.Log{
+ Index: 3,
+ Address: common.HexToAddress(constants.EnsContractAddress),
+ BlockNumber: 5488077,
+ TxIndex: 2,
+ TxHash: common.HexToHash("0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546df"),
+ Topics: []common.Hash{
+ common.HexToHash(constants.NewOwnerEvent.Signature()),
+ common.HexToHash("0x000000000000000000000000c02aaa39b223helloa0e5c4f27ead9083c752553"),
+ common.HexToHash("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba400"),
+ },
+ Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000000000000000af21"),
+}
diff --git a/pkg/omni/shared/helpers/test_helpers/mocks/parser.go b/pkg/omni/shared/helpers/test_helpers/mocks/parser.go
new file mode 100644
index 00000000..5fd8f5fc
--- /dev/null
+++ b/pkg/omni/shared/helpers/test_helpers/mocks/parser.go
@@ -0,0 +1,162 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package mocks
+
+import (
+ "github.com/ethereum/go-ethereum/accounts/abi"
+
+ "github.com/vulcanize/vulcanizedb/pkg/geth"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+// Mock parser
+// Is given ABI string instead of address
+// Performs all other functions of the real parser
+type parser struct {
+ abi string
+ parsedAbi abi.ABI
+}
+
+func NewParser(abi string) *parser {
+
+ return &parser{
+ abi: abi,
+ }
+}
+
+func (p *parser) Abi() string {
+ return p.abi
+}
+
+func (p *parser) ParsedAbi() abi.ABI {
+ return p.parsedAbi
+}
+
+// Retrieves and parses the abi string
+// for the given contract address
+func (p *parser) Parse() error {
+ var err error
+ p.parsedAbi, err = geth.ParseAbi(p.abi)
+
+ return err
+}
+
+// Returns only specified methods, if they meet the criteria
+// Returns as array with methods in same order they were specified
+// Nil wanted array => no events are returned
+func (p *parser) GetSelectMethods(wanted []string) []types.Method {
+ wLen := len(wanted)
+ if wLen == 0 {
+ return nil
+ }
+ methods := make([]types.Method, wLen)
+ for _, m := range p.parsedAbi.Methods {
+ for i, name := range wanted {
+ if name == m.Name && okTypes(m, wanted) {
+ methods[i] = types.NewMethod(m)
+ }
+ }
+ }
+
+ return methods
+}
+
+// Returns wanted methods
+// Empty wanted array => all methods are returned
+// Nil wanted array => no methods are returned
+func (p *parser) GetMethods(wanted []string) []types.Method {
+ if wanted == nil {
+ return nil
+ }
+ methods := make([]types.Method, 0)
+ length := len(wanted)
+ for _, m := range p.parsedAbi.Methods {
+ if length == 0 || stringInSlice(wanted, m.Name) {
+ methods = append(methods, types.NewMethod(m))
+ }
+ }
+
+ return methods
+}
+
+// Returns wanted events as map of types.Events
+// If no events are specified, all events are returned
+func (p *parser) GetEvents(wanted []string) map[string]types.Event {
+ events := map[string]types.Event{}
+
+ for _, e := range p.parsedAbi.Events {
+ if len(wanted) == 0 || stringInSlice(wanted, e.Name) {
+ event := types.NewEvent(e)
+ events[e.Name] = event
+ }
+ }
+
+ return events
+}
+
+func stringInSlice(list []string, s string) bool {
+ for _, b := range list {
+ if b == s {
+ return true
+ }
+ }
+
+ return false
+}
+
+func okTypes(m abi.Method, wanted []string) bool {
+ // Only return method if it has less than 3 arguments, a single output value, and it is a method we want or we want all methods (empty 'wanted' slice)
+ if len(m.Inputs) < 3 && len(m.Outputs) == 1 && (len(wanted) == 0 || stringInSlice(wanted, m.Name)) {
+ // Only return methods if inputs are all of accepted types and output is of the accepted types
+ if !okReturnType(m.Outputs[0]) {
+ return false
+ }
+ for _, input := range m.Inputs {
+ switch input.Type.T {
+ case abi.AddressTy, abi.HashTy, abi.BytesTy, abi.FixedBytesTy:
+ default:
+ return false
+ }
+ }
+
+ return true
+ }
+
+ return false
+}
+
+func okReturnType(arg abi.Argument) bool {
+ wantedTypes := []byte{
+ abi.UintTy,
+ abi.IntTy,
+ abi.BoolTy,
+ abi.StringTy,
+ abi.AddressTy,
+ abi.HashTy,
+ abi.BytesTy,
+ abi.FixedBytesTy,
+ abi.FixedPointTy,
+ }
+
+ for _, ty := range wantedTypes {
+ if arg.Type.T == ty {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/pkg/omni/shared/parser/parser.go b/pkg/omni/shared/parser/parser.go
new file mode 100644
index 00000000..14860f43
--- /dev/null
+++ b/pkg/omni/shared/parser/parser.go
@@ -0,0 +1,218 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package parser
+
+import (
+ "errors"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/vulcanize/vulcanizedb/pkg/geth"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+// Parser is used to fetch and parse contract ABIs
+// It is dependent on etherscan's api
+type Parser interface {
+ Parse(contractAddr string) error
+ ParseAbiStr(abiStr string) error
+ Abi() string
+ ParsedAbi() abi.ABI
+ GetMethods(wanted []string) []types.Method
+ GetSelectMethods(wanted []string) []types.Method
+ GetEvents(wanted []string) map[string]types.Event
+}
+
+type parser struct {
+ client *geth.EtherScanAPI
+ abi string
+ parsedAbi abi.ABI
+}
+
+func NewParser(network string) *parser {
+ url := geth.GenURL(network)
+
+ return &parser{
+ client: geth.NewEtherScanClient(url),
+ }
+}
+
+func (p *parser) Abi() string {
+ return p.abi
+}
+
+func (p *parser) ParsedAbi() abi.ABI {
+ return p.parsedAbi
+}
+
+// Retrieves and parses the abi string
+// for the given contract address
+func (p *parser) Parse(contractAddr string) error {
+ // If the abi is one our locally stored abis, fetch
+ // TODO: Allow users to pass abis through config
+ knownAbi, err := p.lookUp(contractAddr)
+ if err == nil {
+ p.abi = knownAbi
+ p.parsedAbi, err = geth.ParseAbi(knownAbi)
+ return err
+ }
+ // Try getting abi from etherscan
+ abiStr, err := p.client.GetAbi(contractAddr)
+ if err != nil {
+ return err
+ }
+ //TODO: Implement other ways to fetch abi
+ p.abi = abiStr
+ p.parsedAbi, err = geth.ParseAbi(abiStr)
+
+ return err
+}
+
+// Loads and parses an abi from a given abi string
+func (p *parser) ParseAbiStr(abiStr string) error {
+ var err error
+ p.abi = abiStr
+ p.parsedAbi, err = geth.ParseAbi(abiStr)
+
+ return err
+}
+
+func (p *parser) lookUp(contractAddr string) (string, error) {
+ if v, ok := constants.Abis[common.HexToAddress(contractAddr)]; ok {
+ return v, nil
+ }
+
+ return "", errors.New("ABI not present in lookup tabe")
+}
+
+// Returns only specified methods, if they meet the criteria
+// Returns as array with methods in same order they were specified
+// Nil or empty wanted array => no events are returned
+func (p *parser) GetSelectMethods(wanted []string) []types.Method {
+ wLen := len(wanted)
+ if wLen == 0 {
+ return nil
+ }
+ methods := make([]types.Method, wLen)
+ for _, m := range p.parsedAbi.Methods {
+ for i, name := range wanted {
+ if name == m.Name && okTypes(m, wanted) {
+ methods[i] = types.NewMethod(m)
+ }
+ }
+ }
+
+ return methods
+}
+
+// Returns wanted methods
+// Empty wanted array => all methods are returned
+// Nil wanted array => no methods are returned
+func (p *parser) GetMethods(wanted []string) []types.Method {
+ if wanted == nil {
+ return nil
+ }
+ methods := make([]types.Method, 0)
+ length := len(wanted)
+ for _, m := range p.parsedAbi.Methods {
+ if length == 0 || stringInSlice(wanted, m.Name) {
+ methods = append(methods, types.NewMethod(m))
+ }
+ }
+
+ return methods
+}
+
+// Returns wanted events as map of types.Events
+// Empty wanted array => all events are returned
+// Nil wanted array => no events are returned
+func (p *parser) GetEvents(wanted []string) map[string]types.Event {
+ events := map[string]types.Event{}
+ if wanted == nil {
+ return events
+ }
+
+ length := len(wanted)
+ for _, e := range p.parsedAbi.Events {
+ if length == 0 || stringInSlice(wanted, e.Name) {
+ events[e.Name] = types.NewEvent(e)
+ }
+ }
+
+ return events
+}
+
+func okReturnType(arg abi.Argument) bool {
+ wantedTypes := []byte{
+ abi.UintTy,
+ abi.IntTy,
+ abi.BoolTy,
+ abi.StringTy,
+ abi.AddressTy,
+ abi.HashTy,
+ abi.BytesTy,
+ abi.FixedBytesTy,
+ abi.FixedPointTy,
+ }
+
+ for _, ty := range wantedTypes {
+ if arg.Type.T == ty {
+ return true
+ }
+ }
+
+ return false
+}
+
+func okTypes(m abi.Method, wanted []string) bool {
+ // Only return method if it has less than 3 arguments, a single output value, and it is a method we want or we want all methods (empty 'wanted' slice)
+ if len(m.Inputs) < 3 && len(m.Outputs) == 1 && (len(wanted) == 0 || stringInSlice(wanted, m.Name)) {
+ // Only return methods if inputs are all of accepted types and output is of the accepted types
+ if !okReturnType(m.Outputs[0]) {
+ return false
+ }
+ for _, input := range m.Inputs {
+ switch input.Type.T {
+ // Addresses are properly labeled and caught
+ // But hashes tend to not be explicitly labeled and caught
+ // Instead bytes32 are assumed to be hashes
+ case abi.AddressTy, abi.HashTy:
+ case abi.FixedBytesTy:
+ if input.Type.Size != 32 {
+ return false
+ }
+ default:
+ return false
+ }
+ }
+ return true
+ }
+
+ return false
+}
+
+func stringInSlice(list []string, s string) bool {
+ for _, b := range list {
+ if b == s {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/pkg/omni/shared/parser/parser_suite_test.go b/pkg/omni/shared/parser/parser_suite_test.go
new file mode 100644
index 00000000..ccc11fb2
--- /dev/null
+++ b/pkg/omni/shared/parser/parser_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package parser_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestParser(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Parser Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/shared/parser/parser_test.go b/pkg/omni/shared/parser/parser_test.go
new file mode 100644
index 00000000..0b7f3aa3
--- /dev/null
+++ b/pkg/omni/shared/parser/parser_test.go
@@ -0,0 +1,226 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package parser_test
+
+import (
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/geth"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/parser"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+var _ = Describe("Parser", func() {
+
+ var p parser.Parser
+ var err error
+
+ BeforeEach(func() {
+ p = parser.NewParser("")
+ })
+
+ Describe("Mock Parse", func() {
+ It("Uses parses given abi string", func() {
+ mp := mocks.NewParser(constants.DaiAbiString)
+ err = mp.Parse()
+ Expect(err).ToNot(HaveOccurred())
+
+ parsedAbi := mp.ParsedAbi()
+ expectedAbi, err := geth.ParseAbi(constants.DaiAbiString)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(parsedAbi).To(Equal(expectedAbi))
+
+ methods := mp.GetSelectMethods([]string{"balanceOf"})
+ Expect(len(methods)).To(Equal(1))
+ balOf := methods[0]
+ Expect(balOf.Name).To(Equal("balanceOf"))
+ Expect(len(balOf.Args)).To(Equal(1))
+ Expect(len(balOf.Return)).To(Equal(1))
+
+ events := mp.GetEvents([]string{"Transfer"})
+ _, ok := events["Mint"]
+ Expect(ok).To(Equal(false))
+ e, ok := events["Transfer"]
+ Expect(ok).To(Equal(true))
+ Expect(len(e.Fields)).To(Equal(3))
+ })
+ })
+
+ Describe("Parse", func() {
+ It("Fetches and parses abi from etherscan using contract address", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359" // dai contract address
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ expectedAbi := constants.DaiAbiString
+ Expect(p.Abi()).To(Equal(expectedAbi))
+
+ expectedParsedAbi, err := geth.ParseAbi(expectedAbi)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(p.ParsedAbi()).To(Equal(expectedParsedAbi))
+ })
+
+ It("Fails with a normal, non-contract, account address", func() {
+ addr := "0xAb2A8F7cB56D9EC65573BA1bE0f92Fa2Ff7dd165"
+ err = p.Parse(addr)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("GetEvents", func() {
+ It("Returns parsed events", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ events := p.GetEvents([]string{"Transfer"})
+
+ e, ok := events["Transfer"]
+ Expect(ok).To(Equal(true))
+
+ abiTy := e.Fields[0].Type.T
+ Expect(abiTy).To(Equal(abi.AddressTy))
+
+ pgTy := e.Fields[0].PgType
+ Expect(pgTy).To(Equal("CHARACTER VARYING(66)"))
+
+ abiTy = e.Fields[1].Type.T
+ Expect(abiTy).To(Equal(abi.AddressTy))
+
+ pgTy = e.Fields[1].PgType
+ Expect(pgTy).To(Equal("CHARACTER VARYING(66)"))
+
+ abiTy = e.Fields[2].Type.T
+ Expect(abiTy).To(Equal(abi.UintTy))
+
+ pgTy = e.Fields[2].PgType
+ Expect(pgTy).To(Equal("DECIMAL"))
+
+ _, ok = events["Approval"]
+ Expect(ok).To(Equal(false))
+ })
+ })
+
+ Describe("GetSelectMethods", func() {
+ It("Parses and returns only methods specified in passed array", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ methods := p.GetSelectMethods([]string{"balanceOf"})
+ Expect(len(methods)).To(Equal(1))
+
+ balOf := methods[0]
+ Expect(balOf.Name).To(Equal("balanceOf"))
+ Expect(len(balOf.Args)).To(Equal(1))
+ Expect(len(balOf.Return)).To(Equal(1))
+
+ abiTy := balOf.Args[0].Type.T
+ Expect(abiTy).To(Equal(abi.AddressTy))
+
+ pgTy := balOf.Args[0].PgType
+ Expect(pgTy).To(Equal("CHARACTER VARYING(66)"))
+
+ abiTy = balOf.Return[0].Type.T
+ Expect(abiTy).To(Equal(abi.UintTy))
+
+ pgTy = balOf.Return[0].PgType
+ Expect(pgTy).To(Equal("DECIMAL"))
+
+ })
+
+ It("Parses and returns methods in the order they were specified", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ selectMethods := p.GetSelectMethods([]string{"balanceOf", "allowance"})
+ Expect(len(selectMethods)).To(Equal(2))
+
+ balOf := selectMethods[0]
+ allow := selectMethods[1]
+
+ Expect(balOf.Name).To(Equal("balanceOf"))
+ Expect(allow.Name).To(Equal("allowance"))
+ })
+
+ It("Returns nil if given a nil or empty array", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ var nilArr []types.Method
+ selectMethods := p.GetSelectMethods([]string{})
+ Expect(selectMethods).To(Equal(nilArr))
+ selectMethods = p.GetMethods(nil)
+ Expect(selectMethods).To(Equal(nilArr))
+ })
+
+ })
+
+ Describe("GetMethods", func() {
+ It("Parses and returns only methods specified in passed array", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ methods := p.GetMethods([]string{"balanceOf"})
+ Expect(len(methods)).To(Equal(1))
+
+ balOf := methods[0]
+ Expect(balOf.Name).To(Equal("balanceOf"))
+ Expect(len(balOf.Args)).To(Equal(1))
+ Expect(len(balOf.Return)).To(Equal(1))
+
+ abiTy := balOf.Args[0].Type.T
+ Expect(abiTy).To(Equal(abi.AddressTy))
+
+ pgTy := balOf.Args[0].PgType
+ Expect(pgTy).To(Equal("CHARACTER VARYING(66)"))
+
+ abiTy = balOf.Return[0].Type.T
+ Expect(abiTy).To(Equal(abi.UintTy))
+
+ pgTy = balOf.Return[0].PgType
+ Expect(pgTy).To(Equal("DECIMAL"))
+
+ })
+
+ It("Returns nil if given a nil array", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ var nilArr []types.Method
+ selectMethods := p.GetMethods(nil)
+ Expect(selectMethods).To(Equal(nilArr))
+ })
+
+ It("Returns every method if given an empty array", func() {
+ contractAddr := "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
+ err = p.Parse(contractAddr)
+ Expect(err).ToNot(HaveOccurred())
+
+ selectMethods := p.GetMethods([]string{})
+ Expect(len(selectMethods)).To(Equal(22))
+ })
+ })
+})
diff --git a/pkg/omni/shared/poller/poller.go b/pkg/omni/shared/poller/poller.go
new file mode 100644
index 00000000..c1b30a93
--- /dev/null
+++ b/pkg/omni/shared/poller/poller.go
@@ -0,0 +1,292 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package poller
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "strconv"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+type Poller interface {
+ PollContract(con contract.Contract) error
+ PollContractAt(con contract.Contract, blockNumber int64) error
+ FetchContractData(contractAbi, contractAddress, method string, methodArgs []interface{}, result interface{}, blockNumber int64) error
+}
+
+type poller struct {
+ repository.MethodRepository
+ bc core.BlockChain
+ contract contract.Contract
+}
+
+func NewPoller(blockChain core.BlockChain, db *postgres.DB, mode types.Mode) *poller {
+ return &poller{
+ MethodRepository: repository.NewMethodRepository(db, mode),
+ bc: blockChain,
+ }
+}
+
+func (p *poller) PollContract(con contract.Contract) error {
+ for i := con.StartingBlock; i <= con.LastBlock; i++ {
+ p.PollContractAt(con, i)
+ }
+
+ return nil
+}
+
+func (p *poller) PollContractAt(con contract.Contract, blockNumber int64) error {
+ p.contract = con
+ for _, m := range con.Methods {
+ switch len(m.Args) {
+ case 0:
+ if err := p.pollNoArgAt(m, blockNumber); err != nil {
+ return err
+ }
+ case 1:
+ if err := p.pollSingleArgAt(m, blockNumber); err != nil {
+ return err
+ }
+ case 2:
+ if err := p.pollDoubleArgAt(m, blockNumber); err != nil {
+ return err
+ }
+ default:
+ return errors.New("poller error: too many arguments to handle")
+
+ }
+ }
+
+ return nil
+}
+
+func (p *poller) pollNoArgAt(m types.Method, bn int64) error {
+ result := types.Result{
+ Block: bn,
+ Method: m,
+ Inputs: nil,
+ PgType: m.Return[0].PgType,
+ }
+
+ var out interface{}
+ err := p.bc.FetchContractData(p.contract.Abi, p.contract.Address, m.Name, nil, &out, bn)
+ if err != nil {
+ return errors.New(fmt.Sprintf("poller error calling 0 argument method\r\nblock: %d, method: %s, contract: %s\r\nerr: %v", bn, m.Name, p.contract.Address, err))
+ }
+
+ strOut, err := stringify(out)
+ if err != nil {
+ return err
+ }
+
+ // Cache returned value if piping is turned on
+ p.cache(out)
+ result.Output = strOut
+
+ // Persist result immediately
+ err = p.PersistResults([]types.Result{result}, m, p.contract.Address, p.contract.Name)
+ if err != nil {
+ return errors.New(fmt.Sprintf("poller error persisting 0 argument method result\r\nblock: %d, method: %s, contract: %s\r\nerr: %v", bn, m.Name, p.contract.Address, err))
+ }
+
+ return nil
+}
+
+// Use token holder address to poll methods that take 1 address argument (e.g. balanceOf)
+func (p *poller) pollSingleArgAt(m types.Method, bn int64) error {
+ result := types.Result{
+ Block: bn,
+ Method: m,
+ Inputs: make([]interface{}, 1),
+ PgType: m.Return[0].PgType,
+ }
+
+ // Depending on the type of the arg choose
+ // the correct argument set to iterate over
+ var args map[interface{}]bool
+ switch m.Args[0].Type.T {
+ case abi.HashTy, abi.FixedBytesTy:
+ args = p.contract.EmittedHashes
+ case abi.AddressTy:
+ args = p.contract.EmittedAddrs
+ }
+ if len(args) == 0 { // If we haven't collected any args by now we can't call the method
+ return nil
+ }
+ results := make([]types.Result, 0, len(args))
+
+ for arg := range args {
+ in := []interface{}{arg}
+ strIn := []interface{}{contract.StringifyArg(arg)}
+
+ var out interface{}
+ err := p.bc.FetchContractData(p.contract.Abi, p.contract.Address, m.Name, in, &out, bn)
+ if err != nil {
+ return errors.New(fmt.Sprintf("poller error calling 1 argument method\r\nblock: %d, method: %s, contract: %s\r\nerr: %v", bn, m.Name, p.contract.Address, err))
+ }
+ strOut, err := stringify(out)
+ if err != nil {
+ return err
+ }
+ p.cache(out)
+
+ // Write inputs and outputs to result and append result to growing set
+ result.Inputs = strIn
+ result.Output = strOut
+ results = append(results, result)
+ }
+
+ // Persist result set as batch
+ err := p.PersistResults(results, m, p.contract.Address, p.contract.Name)
+ if err != nil {
+ return errors.New(fmt.Sprintf("poller error persisting 1 argument method result\r\nblock: %d, method: %s, contract: %s\r\nerr: %v", bn, m.Name, p.contract.Address, err))
+ }
+
+ return nil
+}
+
+// Use token holder address to poll methods that take 2 address arguments (e.g. allowance)
+func (p *poller) pollDoubleArgAt(m types.Method, bn int64) error {
+ result := types.Result{
+ Block: bn,
+ Method: m,
+ Inputs: make([]interface{}, 2),
+ PgType: m.Return[0].PgType,
+ }
+
+ // Depending on the type of the args choose
+ // the correct argument sets to iterate over
+ var firstArgs map[interface{}]bool
+ switch m.Args[0].Type.T {
+ case abi.HashTy, abi.FixedBytesTy:
+ firstArgs = p.contract.EmittedHashes
+ case abi.AddressTy:
+ firstArgs = p.contract.EmittedAddrs
+ }
+ if len(firstArgs) == 0 {
+ return nil
+ }
+
+ var secondArgs map[interface{}]bool
+ switch m.Args[1].Type.T {
+ case abi.HashTy, abi.FixedBytesTy:
+ secondArgs = p.contract.EmittedHashes
+ case abi.AddressTy:
+ secondArgs = p.contract.EmittedAddrs
+ }
+ if len(secondArgs) == 0 {
+ return nil
+ }
+
+ results := make([]types.Result, 0, len(firstArgs)*len(secondArgs))
+
+ for arg1 := range firstArgs {
+ for arg2 := range secondArgs {
+ in := []interface{}{arg1, arg2}
+ strIn := []interface{}{contract.StringifyArg(arg1), contract.StringifyArg(arg2)}
+
+ var out interface{}
+ err := p.bc.FetchContractData(p.contract.Abi, p.contract.Address, m.Name, in, &out, bn)
+ if err != nil {
+ return errors.New(fmt.Sprintf("poller error calling 2 argument method\r\nblock: %d, method: %s, contract: %s\r\nerr: %v", bn, m.Name, p.contract.Address, err))
+ }
+
+ strOut, err := stringify(out)
+ if err != nil {
+ return err
+ }
+
+ p.cache(out)
+
+ result.Output = strOut
+ result.Inputs = strIn
+ results = append(results, result)
+
+ }
+ }
+
+ err := p.PersistResults(results, m, p.contract.Address, p.contract.Name)
+ if err != nil {
+ return errors.New(fmt.Sprintf("poller error persisting 2 argument method result\r\nblock: %d, method: %s, contract: %s\r\nerr: %v", bn, m.Name, p.contract.Address, err))
+ }
+
+ return nil
+}
+
+// This is just a wrapper around the poller blockchain's FetchContractData method
+func (p *poller) FetchContractData(contractAbi, contractAddress, method string, methodArgs []interface{}, result interface{}, blockNumber int64) error {
+ return p.bc.FetchContractData(contractAbi, contractAddress, method, methodArgs, result, blockNumber)
+}
+
+// This is used to cache an method return value if method piping is turned on
+func (p *poller) cache(out interface{}) {
+ // Cache returned value if piping is turned on
+ if p.contract.Piping {
+ switch out.(type) {
+ case common.Hash:
+ if p.contract.EmittedHashes != nil {
+ p.contract.AddEmittedHash(out.(common.Hash))
+ }
+ case []byte:
+ if p.contract.EmittedHashes != nil && len(out.([]byte)) == 32 {
+ p.contract.AddEmittedHash(common.BytesToHash(out.([]byte)))
+ }
+ case common.Address:
+ if p.contract.EmittedAddrs != nil {
+ p.contract.AddEmittedAddr(out.(common.Address))
+ }
+ default:
+ }
+ }
+}
+
+func stringify(input interface{}) (string, error) {
+ switch input.(type) {
+ case *big.Int:
+ b := input.(*big.Int)
+ return b.String(), nil
+ case common.Address:
+ a := input.(common.Address)
+ return a.String(), nil
+ case common.Hash:
+ h := input.(common.Hash)
+ return h.String(), nil
+ case string:
+ return input.(string), nil
+ case []byte:
+ b := hexutil.Encode(input.([]byte))
+ return b, nil
+ case byte:
+ b := input.(byte)
+ return string(b), nil
+ case bool:
+ return strconv.FormatBool(input.(bool)), nil
+ default:
+ return "", errors.New("error: unhandled return type")
+ }
+}
diff --git a/pkg/omni/shared/poller/poller_suite_test.go b/pkg/omni/shared/poller/poller_suite_test.go
new file mode 100644
index 00000000..9a2ea847
--- /dev/null
+++ b/pkg/omni/shared/poller/poller_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package poller_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestPoller(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Poller Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/shared/poller/poller_test.go b/pkg/omni/shared/poller/poller_test.go
new file mode 100644
index 00000000..b36cecde
--- /dev/null
+++ b/pkg/omni/shared/poller/poller_test.go
@@ -0,0 +1,257 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package poller_test
+
+import (
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/common"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/poller"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+var _ = Describe("Poller", func() {
+
+ var p poller.Poller
+ var con *contract.Contract
+ var db *postgres.DB
+ var bc core.BlockChain
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("Full sync mode", func() {
+ BeforeEach(func() {
+ db, bc = test_helpers.SetupDBandBC()
+ p = poller.NewPoller(bc, db, types.FullSync)
+ })
+
+ Describe("PollContract", func() {
+ It("Polls specified contract methods using contract's argument list", func() {
+ con = test_helpers.SetupTusdContract(nil, []string{"balanceOf"})
+ Expect(con.Abi).To(Equal(constants.TusdAbiString))
+ con.StartingBlock = 6707322
+ con.LastBlock = 6707323
+ con.AddEmittedAddr(common.HexToAddress("0xfE9e8709d3215310075d67E3ed32A380CCf451C8"), common.HexToAddress("0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE"))
+
+ err := p.PollContract(*con)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.BalanceOf{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0xfE9e8709d3215310075d67E3ed32A380CCf451C8' AND block = '6707322'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("66386309548896882859581786"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0xfE9e8709d3215310075d67E3ed32A380CCf451C8' AND block = '6707323'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("66386309548896882859581786"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE' AND block = '6707322'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("17982350181394112023885864"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE' AND block = '6707323'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("17982350181394112023885864"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+ })
+
+ It("Polls specified contract methods using contract's hash list", func() {
+ con = test_helpers.SetupENSContract(nil, []string{"owner"})
+ Expect(con.Abi).To(Equal(constants.ENSAbiString))
+ Expect(len(con.Methods)).To(Equal(1))
+ con.AddEmittedHash(common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"), common.HexToHash("0x7e74a86b6e146964fb965db04dc2590516da77f720bb6759337bf5632415fd86"))
+
+ err := p.PollContractAt(*con, 6885877)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.Owner{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x7e74a86b6e146964fb965db04dc2590516da77f720bb6759337bf5632415fd86' AND block = '6885877'", constants.EnsContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Address).To(Equal("0x546aA2EaE2514494EeaDb7bbb35243348983C59d"))
+ Expect(scanStruct.TokenName).To(Equal("ENS-Registry"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885877'", constants.EnsContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef"))
+ Expect(scanStruct.TokenName).To(Equal("ENS-Registry"))
+ })
+
+ It("Does not poll and persist any methods if none are specified", func() {
+ con = test_helpers.SetupTusdContract(nil, nil)
+ Expect(con.Abi).To(Equal(constants.TusdAbiString))
+ con.StartingBlock = 6707322
+ con.LastBlock = 6707323
+ con.AddEmittedAddr(common.HexToAddress("0xfE9e8709d3215310075d67E3ed32A380CCf451C8"), common.HexToAddress("0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE"))
+
+ err := p.PollContract(*con)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.BalanceOf{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method WHERE who_ = '0xfE9e8709d3215310075d67E3ed32A380CCf451C8' AND block = '6707322'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+
+ Describe("FetchContractData", func() {
+ It("Calls a single contract method", func() {
+ var name = new(string)
+ err := p.FetchContractData(constants.TusdAbiString, constants.TusdContractAddress, "name", nil, &name, 6197514)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(*name).To(Equal("TrueUSD"))
+ })
+ })
+ })
+
+ Describe("Light sync mode", func() {
+ BeforeEach(func() {
+ db, bc = test_helpers.SetupDBandBC()
+ p = poller.NewPoller(bc, db, types.LightSync)
+ })
+
+ Describe("PollContract", func() {
+ It("Polls specified contract methods using contract's token holder address list", func() {
+ con = test_helpers.SetupTusdContract(nil, []string{"balanceOf"})
+ Expect(con.Abi).To(Equal(constants.TusdAbiString))
+ con.StartingBlock = 6707322
+ con.LastBlock = 6707323
+ con.AddEmittedAddr(common.HexToAddress("0xfE9e8709d3215310075d67E3ed32A380CCf451C8"), common.HexToAddress("0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE"))
+
+ err := p.PollContract(*con)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.BalanceOf{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0xfE9e8709d3215310075d67E3ed32A380CCf451C8' AND block = '6707322'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("66386309548896882859581786"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0xfE9e8709d3215310075d67E3ed32A380CCf451C8' AND block = '6707323'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("66386309548896882859581786"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE' AND block = '6707322'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("17982350181394112023885864"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE' AND block = '6707323'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Balance).To(Equal("17982350181394112023885864"))
+ Expect(scanStruct.TokenName).To(Equal("TrueUSD"))
+ })
+
+ It("Polls specified contract methods using contract's hash list", func() {
+ con = test_helpers.SetupENSContract(nil, []string{"owner"})
+ Expect(con.Abi).To(Equal(constants.ENSAbiString))
+ Expect(len(con.Methods)).To(Equal(1))
+ con.AddEmittedHash(common.HexToHash("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae"), common.HexToHash("0x7e74a86b6e146964fb965db04dc2590516da77f720bb6759337bf5632415fd86"))
+
+ err := p.PollContractAt(*con, 6885877)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.Owner{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x7e74a86b6e146964fb965db04dc2590516da77f720bb6759337bf5632415fd86' AND block = '6885877'", constants.EnsContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Address).To(Equal("0x546aA2EaE2514494EeaDb7bbb35243348983C59d"))
+ Expect(scanStruct.TokenName).To(Equal("ENS-Registry"))
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae' AND block = '6885877'", constants.EnsContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Address).To(Equal("0x6090A6e47849629b7245Dfa1Ca21D94cd15878Ef"))
+ Expect(scanStruct.TokenName).To(Equal("ENS-Registry"))
+ })
+
+ It("Does not poll and persist any methods if none are specified", func() {
+ con = test_helpers.SetupTusdContract(nil, nil)
+ Expect(con.Abi).To(Equal(constants.TusdAbiString))
+ con.StartingBlock = 6707322
+ con.LastBlock = 6707323
+ con.AddEmittedAddr(common.HexToAddress("0xfE9e8709d3215310075d67E3ed32A380CCf451C8"), common.HexToAddress("0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE"))
+
+ err := p.PollContract(*con)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.BalanceOf{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method WHERE who_ = '0xfE9e8709d3215310075d67E3ed32A380CCf451C8' AND block = '6707322'", constants.TusdContractAddress)).StructScan(&scanStruct)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("Caches returned values of the appropriate types for downstream method polling if method piping is turned on", func() {
+ con = test_helpers.SetupENSContract(nil, []string{"resolver"})
+ Expect(con.Abi).To(Equal(constants.ENSAbiString))
+ con.StartingBlock = 6921967
+ con.LastBlock = 6921968
+ con.EmittedAddrs = map[interface{}]bool{}
+ con.Piping = false
+ con.AddEmittedHash(common.HexToHash("0x495b6e6efdedb750aa519919b5cf282bdaa86067b82a2293a3ff5723527141e8"))
+ err := p.PollContract(*con)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.Resolver{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.resolver_method WHERE node_ = '0x495b6e6efdedb750aa519919b5cf282bdaa86067b82a2293a3ff5723527141e8' AND block = '6921967'", constants.EnsContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Address).To(Equal("0x5FfC014343cd971B7eb70732021E26C35B744cc4"))
+ Expect(scanStruct.TokenName).To(Equal("ENS-Registry"))
+ Expect(len(con.EmittedAddrs)).To(Equal(0)) // With piping off the address is not saved
+
+ test_helpers.TearDown(db)
+ db, bc = test_helpers.SetupDBandBC()
+ p = poller.NewPoller(bc, db, types.LightSync)
+
+ con.Piping = true
+ err = p.PollContract(*con)
+ Expect(err).ToNot(HaveOccurred())
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.resolver_method WHERE node_ = '0x495b6e6efdedb750aa519919b5cf282bdaa86067b82a2293a3ff5723527141e8' AND block = '6921967'", constants.EnsContractAddress)).StructScan(&scanStruct)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanStruct.Address).To(Equal("0x5FfC014343cd971B7eb70732021E26C35B744cc4"))
+ Expect(scanStruct.TokenName).To(Equal("ENS-Registry"))
+ Expect(len(con.EmittedAddrs)).To(Equal(1)) // With piping on it is saved
+ Expect(con.EmittedAddrs[common.HexToAddress("0x5FfC014343cd971B7eb70732021E26C35B744cc4")]).To(Equal(true))
+ })
+ })
+
+ Describe("FetchContractData", func() {
+ It("Calls a single contract method", func() {
+ var name = new(string)
+ err := p.FetchContractData(constants.TusdAbiString, constants.TusdContractAddress, "name", nil, &name, 6197514)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(*name).To(Equal("TrueUSD"))
+ })
+ })
+ })
+})
diff --git a/pkg/omni/shared/repository/event_repository.go b/pkg/omni/shared/repository/event_repository.go
new file mode 100644
index 00000000..4b599447
--- /dev/null
+++ b/pkg/omni/shared/repository/event_repository.go
@@ -0,0 +1,313 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "github.com/hashicorp/golang-lru"
+
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/light/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+const (
+ // Number of contract address and method ids to keep in cache
+ contractCacheSize = 100
+ eventChacheSize = 1000
+)
+
+// Event repository is used to persist event data into custom tables
+type EventRepository interface {
+ PersistLogs(logs []types.Log, eventInfo types.Event, contractAddr, contractName string) error
+ CreateEventTable(contractAddr string, event types.Event) (bool, error)
+ CreateContractSchema(contractName string) (bool, error)
+ CheckSchemaCache(key string) (interface{}, bool)
+ CheckTableCache(key string) (interface{}, bool)
+}
+
+type eventRepository struct {
+ db *postgres.DB
+ mode types.Mode
+ schemas *lru.Cache // Cache names of recently used schemas to minimize db connections
+ tables *lru.Cache // Cache names of recently used tables to minimize db connections
+}
+
+func NewEventRepository(db *postgres.DB, mode types.Mode) *eventRepository {
+ ccs, _ := lru.New(contractCacheSize)
+ ecs, _ := lru.New(eventChacheSize)
+ return &eventRepository{
+ db: db,
+ mode: mode,
+ schemas: ccs,
+ tables: ecs,
+ }
+}
+
+// Creates a schema for the contract if needed
+// Creates table for the watched contract event if needed
+// Persists converted event log data into this custom table
+func (r *eventRepository) PersistLogs(logs []types.Log, eventInfo types.Event, contractAddr, contractName string) error {
+ if len(logs) == 0 {
+ return errors.New("event repository error: passed empty logs slice")
+ }
+ _, err := r.CreateContractSchema(contractAddr)
+ if err != nil {
+ return err
+ }
+
+ _, err = r.CreateEventTable(contractAddr, eventInfo)
+ if err != nil {
+ return err
+ }
+
+ return r.persistLogs(logs, eventInfo, contractAddr, contractName)
+}
+
+func (r *eventRepository) persistLogs(logs []types.Log, eventInfo types.Event, contractAddr, contractName string) error {
+ var err error
+ switch r.mode {
+ case types.LightSync:
+ err = r.persistLightSyncLogs(logs, eventInfo, contractAddr, contractName)
+ case types.FullSync:
+ err = r.persistFullSyncLogs(logs, eventInfo, contractAddr, contractName)
+ default:
+ return errors.New("event repository error: unhandled mode")
+ }
+
+ return err
+}
+
+// Creates a custom postgres command to persist logs for the given event (compatible with light synced vDB)
+func (r *eventRepository) persistLightSyncLogs(logs []types.Log, eventInfo types.Event, contractAddr, contractName string) error {
+ tx, err := r.db.Begin()
+ if err != nil {
+ return err
+ }
+
+ for _, event := range logs {
+ // Begin pg query string
+ pgStr := fmt.Sprintf("INSERT INTO %s_%s.%s_event ", r.mode.String(), strings.ToLower(contractAddr), strings.ToLower(eventInfo.Name))
+ pgStr = pgStr + "(header_id, token_name, raw_log, log_idx, tx_idx"
+ el := len(event.Values)
+
+ // Preallocate slice of needed capacity and proceed to pack variables into it in same order they appear in string
+ data := make([]interface{}, 0, 5+el)
+ data = append(data,
+ event.Id,
+ contractName,
+ event.Raw,
+ event.LogIndex,
+ event.TransactionIndex)
+
+ // Iterate over inputs and append name to query string and value to input data
+ for inputName, input := range event.Values {
+ pgStr = pgStr + fmt.Sprintf(", %s_", strings.ToLower(inputName)) // Add underscore after to avoid any collisions with reserved pg words
+ data = append(data, input)
+ }
+
+ // For each input entry we created we add its postgres command variable to the string
+ pgStr = pgStr + ") VALUES ($1, $2, $3, $4, $5"
+ for i := 0; i < el; i++ {
+ pgStr = pgStr + fmt.Sprintf(", $%d", i+6)
+ }
+ pgStr = pgStr + ")"
+
+ // Add this query to the transaction
+ _, err = tx.Exec(pgStr, data...)
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+
+ // Mark header as checked for this eventId
+ eventId := strings.ToLower(eventInfo.Name + "_" + contractAddr)
+ err = repository.MarkHeaderCheckedInTransaction(logs[0].Id, tx, eventId) // This assumes all logs are from same block
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+
+ return tx.Commit()
+}
+
+// Creates a custom postgres command to persist logs for the given event (compatible with fully synced vDB)
+func (r *eventRepository) persistFullSyncLogs(logs []types.Log, eventInfo types.Event, contractAddr, contractName string) error {
+ tx, err := r.db.Begin()
+ if err != nil {
+ return err
+ }
+
+ for _, event := range logs {
+ pgStr := fmt.Sprintf("INSERT INTO %s_%s.%s_event ", r.mode.String(), strings.ToLower(contractAddr), strings.ToLower(eventInfo.Name))
+ pgStr = pgStr + "(vulcanize_log_id, token_name, block, tx"
+ el := len(event.Values)
+
+ data := make([]interface{}, 0, 4+el)
+ data = append(data,
+ event.Id,
+ contractName,
+ event.Block,
+ event.Tx)
+
+ for inputName, input := range event.Values {
+ pgStr = pgStr + fmt.Sprintf(", %s_", strings.ToLower(inputName))
+ data = append(data, input)
+ }
+
+ pgStr = pgStr + ") VALUES ($1, $2, $3, $4"
+ for i := 0; i < el; i++ {
+ pgStr = pgStr + fmt.Sprintf(", $%d", i+5)
+ }
+ pgStr = pgStr + ") ON CONFLICT (vulcanize_log_id) DO NOTHING"
+
+ _, err = tx.Exec(pgStr, data...)
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+
+ return tx.Commit()
+}
+
+// Checks for event table and creates it if it does not already exist
+// Returns true if it created a new table; returns false if table already existed
+func (r *eventRepository) CreateEventTable(contractAddr string, event types.Event) (bool, error) {
+ tableID := fmt.Sprintf("%s_%s.%s_event", r.mode.String(), strings.ToLower(contractAddr), strings.ToLower(event.Name))
+ // Check cache before querying pq to see if table exists
+ _, ok := r.tables.Get(tableID)
+ if ok {
+ return false, nil
+ }
+ tableExists, err := r.checkForTable(contractAddr, event.Name)
+ if err != nil {
+ return false, err
+ }
+
+ if !tableExists {
+ err = r.newEventTable(tableID, event)
+ if err != nil {
+ return false, err
+ }
+ }
+
+ // Add table id to cache
+ r.tables.Add(tableID, true)
+
+ return !tableExists, nil
+}
+
+// Creates a table for the given contract and event
+func (r *eventRepository) newEventTable(tableID string, event types.Event) error {
+ // Begin pg string
+ var pgStr = fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s ", tableID)
+ var err error
+
+ // Handle different modes
+ switch r.mode {
+ case types.FullSync:
+ pgStr = pgStr + "(id SERIAL, vulcanize_log_id INTEGER NOT NULL UNIQUE, token_name CHARACTER VARYING(66) NOT NULL, block INTEGER NOT NULL, tx CHARACTER VARYING(66) NOT NULL,"
+
+ // Iterate over event fields, using their name and pgType to grow the string
+ for _, field := range event.Fields {
+ pgStr = pgStr + fmt.Sprintf(" %s_ %s NOT NULL,", strings.ToLower(field.Name), field.PgType)
+ }
+ pgStr = pgStr + " CONSTRAINT log_index_fk FOREIGN KEY (vulcanize_log_id) REFERENCES logs (id) ON DELETE CASCADE)"
+ case types.LightSync:
+ pgStr = pgStr + "(id SERIAL, header_id INTEGER NOT NULL REFERENCES headers (id) ON DELETE CASCADE, token_name CHARACTER VARYING(66) NOT NULL, raw_log JSONB, log_idx INTEGER NOT NULL, tx_idx INTEGER NOT NULL,"
+
+ for _, field := range event.Fields {
+ pgStr = pgStr + fmt.Sprintf(" %s_ %s NOT NULL,", strings.ToLower(field.Name), field.PgType)
+ }
+ pgStr = pgStr + " UNIQUE (header_id, tx_idx, log_idx))"
+ default:
+ return errors.New("unhandled repository mode")
+ }
+
+ _, err = r.db.Exec(pgStr)
+
+ return err
+}
+
+// Checks if a table already exists for the given contract and event
+func (r *eventRepository) checkForTable(contractAddr string, eventName string) (bool, error) {
+ pgStr := fmt.Sprintf("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = '%s_%s' AND table_name = '%s_event')", r.mode.String(), strings.ToLower(contractAddr), strings.ToLower(eventName))
+
+ var exists bool
+ err := r.db.Get(&exists, pgStr)
+
+ return exists, err
+}
+
+// Checks for contract schema and creates it if it does not already exist
+// Returns true if it created a new schema; returns false if schema already existed
+func (r *eventRepository) CreateContractSchema(contractAddr string) (bool, error) {
+ if contractAddr == "" {
+ return false, errors.New("error: no contract address specified")
+ }
+
+ // Check cache before querying pq to see if schema exists
+ _, ok := r.schemas.Get(contractAddr)
+ if ok {
+ return false, nil
+ }
+ schemaExists, err := r.checkForSchema(contractAddr)
+ if err != nil {
+ return false, err
+ }
+ if !schemaExists {
+ err = r.newContractSchema(contractAddr)
+ if err != nil {
+ return false, err
+ }
+ }
+
+ // Add schema name to cache
+ r.schemas.Add(contractAddr, true)
+
+ return !schemaExists, nil
+}
+
+// Creates a schema for the given contract
+func (r *eventRepository) newContractSchema(contractAddr string) error {
+ _, err := r.db.Exec("CREATE SCHEMA IF NOT EXISTS " + r.mode.String() + "_" + strings.ToLower(contractAddr))
+
+ return err
+}
+
+// Checks if a schema already exists for the given contract
+func (r *eventRepository) checkForSchema(contractAddr string) (bool, error) {
+ pgStr := fmt.Sprintf("SELECT EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = '%s_%s')", r.mode.String(), strings.ToLower(contractAddr))
+
+ var exists bool
+ err := r.db.QueryRow(pgStr).Scan(&exists)
+
+ return exists, err
+}
+
+func (r *eventRepository) CheckSchemaCache(key string) (interface{}, bool) {
+ return r.schemas.Get(key)
+}
+
+func (r *eventRepository) CheckTableCache(key string) (interface{}, bool) {
+ return r.tables.Get(key)
+}
diff --git a/pkg/omni/shared/repository/event_repository_test.go b/pkg/omni/shared/repository/event_repository_test.go
new file mode 100644
index 00000000..06cac7d7
--- /dev/null
+++ b/pkg/omni/shared/repository/event_repository_test.go
@@ -0,0 +1,351 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository_test
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+ geth "github.com/ethereum/go-ethereum/core/types"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ fc "github.com/vulcanize/vulcanizedb/pkg/omni/full/converter"
+ lc "github.com/vulcanize/vulcanizedb/pkg/omni/light/converter"
+ lr "github.com/vulcanize/vulcanizedb/pkg/omni/light/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers/mocks"
+ sr "github.com/vulcanize/vulcanizedb/pkg/omni/shared/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+var _ = Describe("Repository", func() {
+ var db *postgres.DB
+ var dataStore sr.EventRepository
+ var err error
+ var log *types.Log
+ var logs []types.Log
+ var con *contract.Contract
+ var vulcanizeLogId int64
+ var wantedEvents = []string{"Transfer"}
+ var wantedMethods = []string{"balanceOf"}
+ var event types.Event
+ var headerID int64
+ var mockEvent = mocks.MockTranferEvent
+ var mockLog1 = mocks.MockTransferLog1
+ var mockLog2 = mocks.MockTransferLog2
+
+ BeforeEach(func() {
+ db, con = test_helpers.SetupTusdRepo(&vulcanizeLogId, wantedEvents, wantedMethods)
+ mockEvent.LogID = vulcanizeLogId
+
+ event = con.Events["Transfer"]
+ err = con.GenerateFilters()
+ Expect(err).ToNot(HaveOccurred())
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("Full sync mode", func() {
+ BeforeEach(func() {
+ dataStore = sr.NewEventRepository(db, types.FullSync)
+ })
+
+ Describe("CreateContractSchema", func() {
+ It("Creates schema if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+
+ It("Caches schema it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ _, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(false))
+
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("CreateEventTable", func() {
+ It("Creates table if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateEventTable(con.Address, event)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateEventTable(con.Address, event)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+
+ It("Caches table it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ tableID := fmt.Sprintf("%s_%s.%s_event", types.FullSync, strings.ToLower(con.Address), strings.ToLower(event.Name))
+ _, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(false))
+
+ created, err = dataStore.CreateEventTable(con.Address, event)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("PersistLogs", func() {
+ BeforeEach(func() {
+ c := fc.NewConverter(con)
+ log, err = c.Convert(mockEvent, event)
+ Expect(err).ToNot(HaveOccurred())
+ })
+
+ It("Persists contract event log values into custom tables", func() {
+ err = dataStore.PersistLogs([]types.Log{*log}, event, con.Address, con.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ b, ok := con.EmittedAddrs[common.HexToAddress("0x000000000000000000000000000000000000Af21")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ b, ok = con.EmittedAddrs[common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391")]
+ Expect(ok).To(Equal(true))
+ Expect(b).To(Equal(true))
+
+ scanLog := test_helpers.TransferLog{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.transfer_event", constants.TusdContractAddress)).StructScan(&scanLog)
+ Expect(err).ToNot(HaveOccurred())
+ expectedLog := test_helpers.TransferLog{
+ Id: 1,
+ VulvanizeLogId: vulcanizeLogId,
+ TokenName: "TrueUSD",
+ Block: 5488076,
+ Tx: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ From: "0x000000000000000000000000000000000000Af21",
+ To: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
+ Value: "1097077688018008265106216665536940668749033598146",
+ }
+ Expect(scanLog).To(Equal(expectedLog))
+ })
+
+ It("Doesn't persist duplicate event logs", func() {
+ // Try to persist the same log twice in a single call
+ err = dataStore.PersistLogs([]types.Log{*log, *log}, event, con.Address, con.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanLog := test_helpers.TransferLog{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.transfer_event", constants.TusdContractAddress)).StructScan(&scanLog)
+ Expect(err).ToNot(HaveOccurred())
+ expectedLog := test_helpers.TransferLog{
+ Id: 1,
+ VulvanizeLogId: vulcanizeLogId,
+ TokenName: "TrueUSD",
+ Block: 5488076,
+ Tx: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ From: "0x000000000000000000000000000000000000Af21",
+ To: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391",
+ Value: "1097077688018008265106216665536940668749033598146",
+ }
+ Expect(scanLog).To(Equal(expectedLog))
+
+ // Attempt to persist the same log again in seperate call
+ err = dataStore.PersistLogs([]types.Log{*log}, event, con.Address, con.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ // Show that no new logs were entered
+ var count int
+ err = db.Get(&count, fmt.Sprintf("SELECT COUNT(*) FROM full_%s.transfer_event", constants.TusdContractAddress))
+ Expect(err).ToNot(HaveOccurred())
+ Expect(count).To(Equal(1))
+ })
+
+ It("Fails with empty log", func() {
+ err = dataStore.PersistLogs([]types.Log{}, event, con.Address, con.Name)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+ })
+
+ Describe("Light sync mode", func() {
+ BeforeEach(func() {
+ dataStore = sr.NewEventRepository(db, types.LightSync)
+ })
+
+ Describe("CreateContractSchema", func() {
+ It("Creates schema if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+
+ It("Caches schema it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ _, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(false))
+
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+
+ It("Caches table it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ tableID := fmt.Sprintf("%s_%s.%s_event", types.LightSync, strings.ToLower(con.Address), strings.ToLower(event.Name))
+ _, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(false))
+
+ created, err = dataStore.CreateEventTable(con.Address, event)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("CreateEventTable", func() {
+ It("Creates table if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateEventTable(con.Address, event)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateEventTable(con.Address, event)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+ })
+
+ Describe("PersistLogs", func() {
+ BeforeEach(func() {
+ headerRepository := repositories.NewHeaderRepository(db)
+ headerID, err = headerRepository.CreateOrUpdateHeader(mocks.MockHeader1)
+ Expect(err).ToNot(HaveOccurred())
+ c := lc.NewConverter(con)
+ logs, err = c.Convert([]geth.Log{mockLog1, mockLog2}, event, headerID)
+ Expect(err).ToNot(HaveOccurred())
+ })
+
+ It("Persists contract event log values into custom tables", func() {
+ hr := lr.NewHeaderRepository(db)
+ err = hr.AddCheckColumn(event.Name + "_" + con.Address)
+ Expect(err).ToNot(HaveOccurred())
+
+ err = dataStore.PersistLogs(logs, event, con.Address, con.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ var count int
+ err = db.Get(&count, fmt.Sprintf("SELECT COUNT(*) FROM light_%s.transfer_event", constants.TusdContractAddress))
+ Expect(err).ToNot(HaveOccurred())
+ Expect(count).To(Equal(2))
+
+ scanLog := test_helpers.LightTransferLog{}
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.transfer_event LIMIT 1", constants.TusdContractAddress)).StructScan(&scanLog)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(scanLog.HeaderID).To(Equal(headerID))
+ Expect(scanLog.TokenName).To(Equal("TrueUSD"))
+ Expect(scanLog.TxIndex).To(Equal(int64(110)))
+ Expect(scanLog.LogIndex).To(Equal(int64(1)))
+ Expect(scanLog.From).To(Equal("0x000000000000000000000000000000000000Af21"))
+ Expect(scanLog.To).To(Equal("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"))
+ Expect(scanLog.Value).To(Equal("1097077688018008265106216665536940668749033598146"))
+
+ var expectedRawLog, rawLog geth.Log
+ err = json.Unmarshal(logs[0].Raw, &expectedRawLog)
+ Expect(err).ToNot(HaveOccurred())
+ err = json.Unmarshal(scanLog.RawLog, &rawLog)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(rawLog).To(Equal(expectedRawLog))
+ })
+
+ It("Doesn't persist duplicate event logs", func() {
+ hr := lr.NewHeaderRepository(db)
+ err = hr.AddCheckColumn(event.Name + "_" + con.Address)
+ Expect(err).ToNot(HaveOccurred())
+
+ // Try and fail to persist the same log twice in a single call
+ err = dataStore.PersistLogs([]types.Log{logs[0], logs[0]}, event, con.Address, con.Name)
+ Expect(err).To(HaveOccurred())
+
+ // Successfuly persist the two unique logs
+ err = dataStore.PersistLogs(logs, event, con.Address, con.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ // Try and fail to persist the same logs again in separate call
+ err = dataStore.PersistLogs([]types.Log{*log}, event, con.Address, con.Name)
+ Expect(err).To(HaveOccurred())
+
+ // Show that no new logs were entered
+ var count int
+ err = db.Get(&count, fmt.Sprintf("SELECT COUNT(*) FROM light_%s.transfer_event", constants.TusdContractAddress))
+ Expect(err).ToNot(HaveOccurred())
+ Expect(count).To(Equal(2))
+ })
+
+ It("Fails if the persisted event does not have a corresponding eventID column in the checked_headers table", func() {
+ err = dataStore.PersistLogs(logs, event, con.Address, con.Name)
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("Fails with empty log", func() {
+ err = dataStore.PersistLogs([]types.Log{}, event, con.Address, con.Name)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+ })
+})
diff --git a/pkg/omni/shared/repository/method_repository.go b/pkg/omni/shared/repository/method_repository.go
new file mode 100644
index 00000000..4231404b
--- /dev/null
+++ b/pkg/omni/shared/repository/method_repository.go
@@ -0,0 +1,227 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "github.com/hashicorp/golang-lru"
+
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+const methodCacheSize = 1000
+
+type MethodRepository interface {
+ PersistResults(results []types.Result, methodInfo types.Method, contractAddr, contractName string) error
+ CreateMethodTable(contractAddr string, method types.Method) (bool, error)
+ CreateContractSchema(contractAddr string) (bool, error)
+ CheckSchemaCache(key string) (interface{}, bool)
+ CheckTableCache(key string) (interface{}, bool)
+}
+
+type methodRepository struct {
+ *postgres.DB
+ mode types.Mode
+ schemas *lru.Cache // Cache names of recently used schemas to minimize db connections
+ tables *lru.Cache // Cache names of recently used tables to minimize db connections
+}
+
+func NewMethodRepository(db *postgres.DB, mode types.Mode) *methodRepository {
+ ccs, _ := lru.New(contractCacheSize)
+ mcs, _ := lru.New(methodCacheSize)
+ return &methodRepository{
+ DB: db,
+ mode: mode,
+ schemas: ccs,
+ tables: mcs,
+ }
+}
+
+// Creates a schema for the contract if needed
+// Creates table for the contract method if needed
+// Persists method polling data into this custom table
+func (r *methodRepository) PersistResults(results []types.Result, methodInfo types.Method, contractAddr, contractName string) error {
+ if len(results) == 0 {
+ return errors.New("method repository error: passed empty results slice")
+ }
+ _, err := r.CreateContractSchema(contractAddr)
+ if err != nil {
+ return err
+ }
+
+ _, err = r.CreateMethodTable(contractAddr, methodInfo)
+ if err != nil {
+ return err
+ }
+
+ return r.persistResults(results, methodInfo, contractAddr, contractName)
+}
+
+// Creates a custom postgres command to persist logs for the given event
+func (r *methodRepository) persistResults(results []types.Result, methodInfo types.Method, contractAddr, contractName string) error {
+ tx, err := r.DB.Begin()
+ if err != nil {
+ return err
+ }
+
+ for _, result := range results {
+ // Begin postgres string
+ pgStr := fmt.Sprintf("INSERT INTO %s_%s.%s_method ", r.mode.String(), strings.ToLower(contractAddr), strings.ToLower(result.Name))
+ pgStr = pgStr + "(token_name, block"
+ ml := len(result.Args)
+
+ // Preallocate slice of needed capacity and proceed to pack variables into it in same order they appear in string
+ data := make([]interface{}, 0, 3+ml)
+ data = append(data,
+ contractName,
+ result.Block)
+
+ // Iterate over method args and return value, adding names
+ // to the string and pushing values to the slice
+ for i, arg := range result.Args {
+ pgStr = pgStr + fmt.Sprintf(", %s_", strings.ToLower(arg.Name)) // Add underscore after to avoid any collisions with reserved pg words
+ data = append(data, result.Inputs[i])
+ }
+ pgStr = pgStr + ", returned) VALUES ($1, $2"
+ data = append(data, result.Output)
+
+ // For each input entry we created we add its postgres command variable to the string
+ for i := 0; i <= ml; i++ {
+ pgStr = pgStr + fmt.Sprintf(", $%d", i+3)
+ }
+ pgStr = pgStr + ")"
+
+ // Add this query to the transaction
+ _, err = tx.Exec(pgStr, data...)
+ if err != nil {
+ tx.Rollback()
+ return err
+ }
+ }
+
+ return tx.Commit()
+}
+
+// Checks for event table and creates it if it does not already exist
+func (r *methodRepository) CreateMethodTable(contractAddr string, method types.Method) (bool, error) {
+ tableID := fmt.Sprintf("%s_%s.%s_method", r.mode.String(), strings.ToLower(contractAddr), strings.ToLower(method.Name))
+
+ // Check cache before querying pq to see if table exists
+ _, ok := r.tables.Get(tableID)
+ if ok {
+ return false, nil
+ }
+ tableExists, err := r.checkForTable(contractAddr, method.Name)
+ if err != nil {
+ return false, err
+ }
+ if !tableExists {
+ err = r.newMethodTable(tableID, method)
+ if err != nil {
+ return false, err
+ }
+ }
+
+ // Add schema name to cache
+ r.tables.Add(tableID, true)
+
+ return !tableExists, nil
+}
+
+// Creates a table for the given contract and event
+func (r *methodRepository) newMethodTable(tableID string, method types.Method) error {
+ // Begin pg string
+ pgStr := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s ", tableID)
+ pgStr = pgStr + "(id SERIAL, token_name CHARACTER VARYING(66) NOT NULL, block INTEGER NOT NULL,"
+
+ // Iterate over method inputs and outputs, using their name and pgType to grow the string
+ for _, arg := range method.Args {
+ pgStr = pgStr + fmt.Sprintf(" %s_ %s NOT NULL,", strings.ToLower(arg.Name), arg.PgType)
+ }
+
+ pgStr = pgStr + fmt.Sprintf(" returned %s NOT NULL)", method.Return[0].PgType)
+
+ _, err := r.DB.Exec(pgStr)
+
+ return err
+}
+
+// Checks if a table already exists for the given contract and event
+func (r *methodRepository) checkForTable(contractAddr string, methodName string) (bool, error) {
+ pgStr := fmt.Sprintf("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = '%s_%s' AND table_name = '%s_method')", r.mode.String(), strings.ToLower(contractAddr), strings.ToLower(methodName))
+ var exists bool
+ err := r.DB.Get(&exists, pgStr)
+
+ return exists, err
+}
+
+// Checks for contract schema and creates it if it does not already exist
+func (r *methodRepository) CreateContractSchema(contractAddr string) (bool, error) {
+ if contractAddr == "" {
+ return false, errors.New("error: no contract address specified")
+ }
+
+ // Check cache before querying pq to see if schema exists
+ _, ok := r.schemas.Get(contractAddr)
+ if ok {
+ return false, nil
+ }
+ schemaExists, err := r.checkForSchema(contractAddr)
+ if err != nil {
+ return false, err
+ }
+ if !schemaExists {
+ err = r.newContractSchema(contractAddr)
+ if err != nil {
+ return false, err
+ }
+ }
+
+ // Add schema name to cache
+ r.schemas.Add(contractAddr, true)
+
+ return !schemaExists, nil
+}
+
+// Creates a schema for the given contract
+func (r *methodRepository) newContractSchema(contractAddr string) error {
+ _, err := r.DB.Exec("CREATE SCHEMA IF NOT EXISTS " + r.mode.String() + "_" + strings.ToLower(contractAddr))
+
+ return err
+}
+
+// Checks if a schema already exists for the given contract
+func (r *methodRepository) checkForSchema(contractAddr string) (bool, error) {
+ pgStr := fmt.Sprintf("SELECT EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = '%s_%s')", r.mode.String(), strings.ToLower(contractAddr))
+
+ var exists bool
+ err := r.DB.Get(&exists, pgStr)
+
+ return exists, err
+}
+
+func (r *methodRepository) CheckSchemaCache(key string) (interface{}, bool) {
+ return r.schemas.Get(key)
+}
+
+func (r *methodRepository) CheckTableCache(key string) (interface{}, bool) {
+ return r.tables.Get(key)
+}
diff --git a/pkg/omni/shared/repository/method_repository_test.go b/pkg/omni/shared/repository/method_repository_test.go
new file mode 100644
index 00000000..c6936e8a
--- /dev/null
+++ b/pkg/omni/shared/repository/method_repository_test.go
@@ -0,0 +1,240 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository_test
+
+import (
+ "fmt"
+ "strings"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+var _ = Describe("Repository", func() {
+ var db *postgres.DB
+ var dataStore repository.MethodRepository
+ var con *contract.Contract
+ var err error
+ var mockResult types.Result
+ var method types.Method
+
+ BeforeEach(func() {
+ con = test_helpers.SetupTusdContract([]string{}, []string{"balanceOf"})
+ Expect(len(con.Methods)).To(Equal(1))
+ method = con.Methods[0]
+ mockResult = types.Result{
+ Method: method,
+ PgType: method.Return[0].PgType,
+ Inputs: make([]interface{}, 1),
+ Output: new(interface{}),
+ Block: 6707323,
+ }
+ mockResult.Inputs[0] = "0xfE9e8709d3215310075d67E3ed32A380CCf451C8"
+ mockResult.Output = "66386309548896882859581786"
+ db, _ = test_helpers.SetupDBandBC()
+ dataStore = repository.NewMethodRepository(db, types.FullSync)
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("Full Sync Mode", func() {
+ BeforeEach(func() {
+ dataStore = repository.NewMethodRepository(db, types.FullSync)
+ })
+
+ Describe("CreateContractSchema", func() {
+ It("Creates schema if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(constants.TusdContractAddress)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateContractSchema(constants.TusdContractAddress)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+
+ It("Caches schema it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ _, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(false))
+
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("CreateMethodTable", func() {
+ It("Creates table if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(constants.TusdContractAddress)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateMethodTable(constants.TusdContractAddress, method)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateMethodTable(constants.TusdContractAddress, method)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+
+ It("Caches table it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ tableID := fmt.Sprintf("%s_%s.%s_method", types.FullSync, strings.ToLower(con.Address), strings.ToLower(method.Name))
+ _, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(false))
+
+ created, err = dataStore.CreateMethodTable(con.Address, method)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("PersistResult", func() {
+ It("Persists result from method polling in custom pg table", func() {
+ err = dataStore.PersistResults([]types.Result{mockResult}, method, con.Address, con.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.BalanceOf{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.balanceof_method", constants.TusdContractAddress)).StructScan(&scanStruct)
+ expectedLog := test_helpers.BalanceOf{
+ Id: 1,
+ TokenName: "TrueUSD",
+ Block: 6707323,
+ Address: "0xfE9e8709d3215310075d67E3ed32A380CCf451C8",
+ Balance: "66386309548896882859581786",
+ }
+ Expect(scanStruct).To(Equal(expectedLog))
+ })
+
+ It("Fails with empty result", func() {
+ err = dataStore.PersistResults([]types.Result{}, method, con.Address, con.Name)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+ })
+
+ Describe("Light Sync Mode", func() {
+ BeforeEach(func() {
+ dataStore = repository.NewMethodRepository(db, types.LightSync)
+ })
+
+ Describe("CreateContractSchema", func() {
+ It("Creates schema if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(constants.TusdContractAddress)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateContractSchema(constants.TusdContractAddress)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+
+ It("Caches schema it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ _, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(false))
+
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckSchemaCache(con.Address)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("CreateMethodTable", func() {
+ It("Creates table if it doesn't exist", func() {
+ created, err := dataStore.CreateContractSchema(constants.TusdContractAddress)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateMethodTable(constants.TusdContractAddress, method)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ created, err = dataStore.CreateMethodTable(constants.TusdContractAddress, method)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(false))
+ })
+
+ It("Caches table it creates so that it does not need to repeatedly query the database to check for it's existence", func() {
+ created, err := dataStore.CreateContractSchema(con.Address)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ tableID := fmt.Sprintf("%s_%s.%s_method", types.LightSync, strings.ToLower(con.Address), strings.ToLower(method.Name))
+ _, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(false))
+
+ created, err = dataStore.CreateMethodTable(con.Address, method)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(created).To(Equal(true))
+
+ v, ok := dataStore.CheckTableCache(tableID)
+ Expect(ok).To(Equal(true))
+ Expect(v).To(Equal(true))
+ })
+ })
+
+ Describe("PersistResult", func() {
+ It("Persists result from method polling in custom pg table for light sync mode vDB", func() {
+ err = dataStore.PersistResults([]types.Result{mockResult}, method, con.Address, con.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ scanStruct := test_helpers.BalanceOf{}
+
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.balanceof_method", constants.TusdContractAddress)).StructScan(&scanStruct)
+ expectedLog := test_helpers.BalanceOf{
+ Id: 1,
+ TokenName: "TrueUSD",
+ Block: 6707323,
+ Address: "0xfE9e8709d3215310075d67E3ed32A380CCf451C8",
+ Balance: "66386309548896882859581786",
+ }
+ Expect(scanStruct).To(Equal(expectedLog))
+ })
+
+ It("Fails with empty result", func() {
+ err = dataStore.PersistResults([]types.Result{}, method, con.Address, con.Name)
+ Expect(err).To(HaveOccurred())
+ })
+ })
+ })
+})
diff --git a/pkg/omni/shared/repository/repository_suite_test.go b/pkg/omni/shared/repository/repository_suite_test.go
new file mode 100644
index 00000000..a1bfc548
--- /dev/null
+++ b/pkg/omni/shared/repository/repository_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package repository_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestRepository(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Shared Repository Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/shared/retriever/address_retriever.go b/pkg/omni/shared/retriever/address_retriever.go
new file mode 100644
index 00000000..f56d448f
--- /dev/null
+++ b/pkg/omni/shared/retriever/address_retriever.go
@@ -0,0 +1,120 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever
+
+import (
+ "fmt"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+)
+
+// Address retriever is used to retrieve the addresses associated with a contract
+type AddressRetriever interface {
+ RetrieveTokenHolderAddresses(info contract.Contract) (map[common.Address]bool, error)
+}
+
+type addressRetriever struct {
+ db *postgres.DB
+ mode types.Mode
+}
+
+func NewAddressRetriever(db *postgres.DB, mode types.Mode) (r *addressRetriever) {
+ return &addressRetriever{
+ db: db,
+ mode: mode,
+ }
+}
+
+// Method to retrieve list of token-holding/contract-related addresses by iterating over available events
+// This generic method should work whether or not the argument/input names of the events meet the expected standard
+// This could be generalized to iterate over ALL events and pull out any address arguments
+func (r *addressRetriever) RetrieveTokenHolderAddresses(info contract.Contract) (map[common.Address]bool, error) {
+ addrList := make([]string, 0)
+
+ _, ok := info.Filters["Transfer"]
+ if ok {
+ addrs, err := r.retrieveTransferAddresses(info)
+ if err != nil {
+ return nil, err
+ }
+ addrList = append(addrList, addrs...)
+ }
+
+ _, ok = info.Filters["Mint"]
+ if ok {
+ addrs, err := r.retrieveTokenMintees(info)
+ if err != nil {
+ return nil, err
+ }
+ addrList = append(addrList, addrs...)
+ }
+
+ contractAddresses := make(map[common.Address]bool)
+ for _, addr := range addrList {
+ contractAddresses[common.HexToAddress(addr)] = true
+ }
+
+ return contractAddresses, nil
+}
+
+func (r *addressRetriever) retrieveTransferAddresses(con contract.Contract) ([]string, error) {
+ transferAddrs := make([]string, 0)
+ event := con.Events["Transfer"]
+
+ for _, field := range event.Fields { // Iterate over event fields, finding the ones with address type
+
+ if field.Type.T == abi.AddressTy { // If they have address type, retrieve those addresses
+ addrs := make([]string, 0)
+ pgStr := fmt.Sprintf("SELECT %s_ FROM %s_%s.%s_event", strings.ToLower(field.Name), r.mode.String(), strings.ToLower(con.Address), strings.ToLower(event.Name))
+ err := r.db.Select(&addrs, pgStr)
+ if err != nil {
+ return []string{}, err
+ }
+
+ transferAddrs = append(transferAddrs, addrs...) // And append them to the growing list
+ }
+ }
+
+ return transferAddrs, nil
+}
+
+func (r *addressRetriever) retrieveTokenMintees(con contract.Contract) ([]string, error) {
+ mintAddrs := make([]string, 0)
+ event := con.Events["Mint"]
+
+ for _, field := range event.Fields { // Iterate over event fields, finding the ones with address type
+
+ if field.Type.T == abi.AddressTy { // If they have address type, retrieve those addresses
+ addrs := make([]string, 0)
+ pgStr := fmt.Sprintf("SELECT %s_ FROM %s_%s.%s_event", strings.ToLower(field.Name), r.mode.String(), strings.ToLower(con.Address), strings.ToLower(event.Name))
+ err := r.db.Select(&addrs, pgStr)
+ if err != nil {
+ return []string{}, err
+ }
+
+ mintAddrs = append(mintAddrs, addrs...) // And append them to the growing list
+ }
+ }
+
+ return mintAddrs, nil
+}
diff --git a/pkg/omni/shared/retriever/address_retriever_test.go b/pkg/omni/shared/retriever/address_retriever_test.go
new file mode 100644
index 00000000..48f45531
--- /dev/null
+++ b/pkg/omni/shared/retriever/address_retriever_test.go
@@ -0,0 +1,107 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever_test
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/full/converter"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/constants"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/contract"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/helpers/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/repository"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/retriever"
+ "github.com/vulcanize/vulcanizedb/pkg/omni/shared/types"
+)
+
+var mockEvent = core.WatchedEvent{
+ Name: constants.TransferEvent.String(),
+ BlockNumber: 5488076,
+ Address: constants.TusdContractAddress,
+ TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae",
+ Index: 110,
+ Topic0: constants.TransferEvent.Signature(),
+ Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21",
+ Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391",
+ Topic3: "",
+ Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe",
+}
+
+var _ = Describe("Address Retriever Test", func() {
+ var db *postgres.DB
+ var dataStore repository.EventRepository
+ var err error
+ var info *contract.Contract
+ var vulcanizeLogId int64
+ var log *types.Log
+ var r retriever.AddressRetriever
+ var addresses map[common.Address]bool
+ var wantedEvents = []string{"Transfer"}
+
+ BeforeEach(func() {
+ db, info = test_helpers.SetupTusdRepo(&vulcanizeLogId, wantedEvents, []string{})
+ mockEvent.LogID = vulcanizeLogId
+
+ event := info.Events["Transfer"]
+ err = info.GenerateFilters()
+ Expect(err).ToNot(HaveOccurred())
+
+ c := converter.NewConverter(info)
+ log, err = c.Convert(mockEvent, event)
+ Expect(err).ToNot(HaveOccurred())
+
+ dataStore = repository.NewEventRepository(db, types.FullSync)
+ dataStore.PersistLogs([]types.Log{*log}, event, info.Address, info.Name)
+ Expect(err).ToNot(HaveOccurred())
+
+ r = retriever.NewAddressRetriever(db, types.FullSync)
+ })
+
+ AfterEach(func() {
+ test_helpers.TearDown(db)
+ })
+
+ Describe("RetrieveTokenHolderAddresses", func() {
+ It("Retrieves a list of token holder addresses from persisted event logs", func() {
+ addresses, err = r.RetrieveTokenHolderAddresses(*info)
+ Expect(err).ToNot(HaveOccurred())
+
+ _, ok := addresses[common.HexToAddress("0x000000000000000000000000000000000000000000000000000000000000af21")]
+ Expect(ok).To(Equal(true))
+
+ _, ok = addresses[common.HexToAddress("0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391")]
+ Expect(ok).To(Equal(true))
+
+ _, ok = addresses[common.HexToAddress("0x")]
+ Expect(ok).To(Equal(false))
+
+ _, ok = addresses[common.HexToAddress(constants.TusdContractAddress)]
+ Expect(ok).To(Equal(false))
+
+ })
+
+ It("Returns empty list when empty contract info is used", func() {
+ addresses, err = r.RetrieveTokenHolderAddresses(contract.Contract{})
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(addresses)).To(Equal(0))
+ })
+ })
+})
diff --git a/pkg/omni/shared/retriever/retriever_suite_test.go b/pkg/omni/shared/retriever/retriever_suite_test.go
new file mode 100644
index 00000000..b46c31fd
--- /dev/null
+++ b/pkg/omni/shared/retriever/retriever_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package retriever_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestRetriever(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Address Retriever Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/omni/shared/transformer/interface.go b/pkg/omni/shared/transformer/interface.go
new file mode 100644
index 00000000..42a241df
--- /dev/null
+++ b/pkg/omni/shared/transformer/interface.go
@@ -0,0 +1,32 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer
+
+// Used to extract any/all events and a subset of method (state variable)
+// data for any contract and persists it to custom postgres tables in vDB
+type Transformer interface {
+ SetEvents(contractAddr string, filterSet []string)
+ SetEventArgs(contractAddr string, filterSet []string)
+ SetMethods(contractAddr string, filterSet []string)
+ SetMethodArgs(contractAddr string, filterSet []string)
+ SetStartingBlock(contractAddr string, start int64)
+ SetCreateAddrList(contractAddr string, on bool)
+ SetCreateHashList(contractAddr string, on bool)
+ SetPiping(contractAddr string, on bool)
+ Init() error
+ Execute() error
+}
diff --git a/pkg/omni/shared/types/event.go b/pkg/omni/shared/types/event.go
new file mode 100644
index 00000000..8d801d15
--- /dev/null
+++ b/pkg/omni/shared/types/event.go
@@ -0,0 +1,96 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package types
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+type Event struct {
+ Name string
+ Anonymous bool
+ Fields []Field
+}
+
+type Field struct {
+ abi.Argument // Name, Type, Indexed
+ PgType string // Holds type used when committing data held in this field to postgres
+}
+
+// Struct to hold instance of an event log data
+type Log struct {
+ Id int64 // VulcanizeIdLog for full sync and header ID for light sync omni watcher
+ Values map[string]string // Map of event input names to their values
+
+ // Used for full sync only
+ Block int64
+ Tx string
+
+ // Used for lightSync only
+ LogIndex uint
+ TransactionIndex uint
+ Raw []byte // json.Unmarshalled byte array of geth/core/types.Log{}
+}
+
+// Unpack abi.Event into our custom Event struct
+func NewEvent(e abi.Event) Event {
+ fields := make([]Field, len(e.Inputs))
+ for i, input := range e.Inputs {
+ fields[i] = Field{}
+ fields[i].Name = input.Name
+ fields[i].Type = input.Type
+ fields[i].Indexed = input.Indexed
+ // Fill in pg type based on abi type
+ switch fields[i].Type.T {
+ case abi.HashTy, abi.AddressTy:
+ fields[i].PgType = "CHARACTER VARYING(66)"
+ case abi.IntTy, abi.UintTy:
+ fields[i].PgType = "DECIMAL"
+ case abi.BoolTy:
+ fields[i].PgType = "BOOLEAN"
+ case abi.BytesTy, abi.FixedBytesTy:
+ fields[i].PgType = "BYTEA"
+ case abi.ArrayTy:
+ fields[i].PgType = "TEXT[]"
+ case abi.FixedPointTy:
+ fields[i].PgType = "MONEY" // use shopspring/decimal for fixed point numbers in go and money type in postgres?
+ default:
+ fields[i].PgType = "TEXT"
+ }
+ }
+
+ return Event{
+ Name: e.Name,
+ Anonymous: e.Anonymous,
+ Fields: fields,
+ }
+}
+
+func (e Event) Sig() common.Hash {
+ types := make([]string, len(e.Fields))
+
+ for i, input := range e.Fields {
+ types[i] = input.Type.String()
+ }
+
+ return common.BytesToHash(crypto.Keccak256([]byte(fmt.Sprintf("%v(%v)", e.Name, strings.Join(types, ",")))))
+}
diff --git a/pkg/omni/shared/types/method.go b/pkg/omni/shared/types/method.go
new file mode 100644
index 00000000..fbd3e25a
--- /dev/null
+++ b/pkg/omni/shared/types/method.go
@@ -0,0 +1,111 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package types
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+type Method struct {
+ Name string
+ Const bool
+ Args []Field
+ Return []Field
+}
+
+// Struct to hold instance of result from method call with given inputs and block
+type Result struct {
+ Method
+ Inputs []interface{} // Will only use addresses
+ Output interface{}
+ PgType string // Holds output pg type
+ Block int64
+}
+
+// Unpack abi.Method into our custom Method struct
+func NewMethod(m abi.Method) Method {
+ inputs := make([]Field, len(m.Inputs))
+ for i, input := range m.Inputs {
+ inputs[i] = Field{}
+ inputs[i].Name = input.Name
+ inputs[i].Type = input.Type
+ inputs[i].Indexed = input.Indexed
+ switch inputs[i].Type.T {
+ case abi.HashTy, abi.AddressTy:
+ inputs[i].PgType = "CHARACTER VARYING(66)"
+ case abi.IntTy, abi.UintTy:
+ inputs[i].PgType = "DECIMAL"
+ case abi.BoolTy:
+ inputs[i].PgType = "BOOLEAN"
+ case abi.BytesTy, abi.FixedBytesTy:
+ inputs[i].PgType = "BYTEA"
+ case abi.ArrayTy:
+ inputs[i].PgType = "TEXT[]"
+ case abi.FixedPointTy:
+ inputs[i].PgType = "MONEY" // use shopspring/decimal for fixed point numbers in go and money type in postgres?
+ default:
+ inputs[i].PgType = "TEXT"
+ }
+ }
+
+ outputs := make([]Field, len(m.Outputs))
+ for i, output := range m.Outputs {
+ outputs[i] = Field{}
+ outputs[i].Name = output.Name
+ outputs[i].Type = output.Type
+ outputs[i].Indexed = output.Indexed
+ switch outputs[i].Type.T {
+ case abi.HashTy, abi.AddressTy:
+ outputs[i].PgType = "CHARACTER VARYING(66)"
+ case abi.IntTy, abi.UintTy:
+ outputs[i].PgType = "DECIMAL"
+ case abi.BoolTy:
+ outputs[i].PgType = "BOOLEAN"
+ case abi.BytesTy, abi.FixedBytesTy:
+ outputs[i].PgType = "BYTEA"
+ case abi.ArrayTy:
+ outputs[i].PgType = "TEXT[]"
+ case abi.FixedPointTy:
+ outputs[i].PgType = "MONEY" // use shopspring/decimal for fixed point numbers in go and money type in postgres?
+ default:
+ outputs[i].PgType = "TEXT"
+ }
+ }
+
+ return Method{
+ Name: m.Name,
+ Const: m.Const,
+ Args: inputs,
+ Return: outputs,
+ }
+}
+
+func (m Method) Sig() common.Hash {
+ types := make([]string, len(m.Args))
+ i := 0
+ for _, arg := range m.Args {
+ types[i] = arg.Type.String()
+ i++
+ }
+
+ return common.BytesToHash(crypto.Keccak256([]byte(fmt.Sprintf("%v(%v)", m.Name, strings.Join(types, ",")))))
+}
diff --git a/pkg/omni/shared/types/mode.go b/pkg/omni/shared/types/mode.go
new file mode 100644
index 00000000..71e5c531
--- /dev/null
+++ b/pkg/omni/shared/types/mode.go
@@ -0,0 +1,64 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package types
+
+import "fmt"
+
+type Mode int
+
+const (
+ LightSync Mode = iota
+ FullSync
+)
+
+func (mode Mode) IsValid() bool {
+ return mode >= LightSync && mode <= FullSync
+}
+
+func (mode Mode) String() string {
+ switch mode {
+ case LightSync:
+ return "light"
+ case FullSync:
+ return "full"
+ default:
+ return "unknown"
+ }
+}
+
+func (mode Mode) MarshalText() ([]byte, error) {
+ switch mode {
+ case LightSync:
+ return []byte("light"), nil
+ case FullSync:
+ return []byte("full"), nil
+ default:
+ return nil, fmt.Errorf("omni watcher: unknown mode %d, want LightSync or FullSync", mode)
+ }
+}
+
+func (mode *Mode) UnmarshalText(text []byte) error {
+ switch string(text) {
+ case "light":
+ *mode = LightSync
+ case "full":
+ *mode = FullSync
+ default:
+ return fmt.Errorf(`omni watcher: unknown mode %q, want "light" or "full"`, text)
+ }
+ return nil
+}
diff --git a/pkg/transformers/bite/bite_suite_test.go b/pkg/transformers/bite/bite_suite_test.go
index a8d60f0d..b85d4a0a 100644
--- a/pkg/transformers/bite/bite_suite_test.go
+++ b/pkg/transformers/bite/bite_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite_test
diff --git a/pkg/transformers/bite/config.go b/pkg/transformers/bite/config.go
index fa6cace7..e6fcff04 100644
--- a/pkg/transformers/bite/config.go
+++ b/pkg/transformers/bite/config.go
@@ -1,18 +1,18 @@
-/*
- * Copyright 2018 Vulcanize
- *
- * 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.
- */
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite
diff --git a/pkg/transformers/bite/converter.go b/pkg/transformers/bite/converter.go
index e346024e..6d5b7e2f 100644
--- a/pkg/transformers/bite/converter.go
+++ b/pkg/transformers/bite/converter.go
@@ -1,18 +1,18 @@
-/*
- * Copyright 2018 Vulcanize
- *
- * 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.
- */
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite
diff --git a/pkg/transformers/bite/converter_test.go b/pkg/transformers/bite/converter_test.go
index 7a077ef4..4217defc 100644
--- a/pkg/transformers/bite/converter_test.go
+++ b/pkg/transformers/bite/converter_test.go
@@ -1,18 +1,18 @@
-/*
- * Copyright 2018 Vulcanize
- *
- * 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.
- */
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite_test
diff --git a/pkg/transformers/bite/entity.go b/pkg/transformers/bite/entity.go
index 9270eebb..16fbdf58 100644
--- a/pkg/transformers/bite/entity.go
+++ b/pkg/transformers/bite/entity.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite
diff --git a/pkg/transformers/bite/model.go b/pkg/transformers/bite/model.go
index a0580c89..e2fde40a 100644
--- a/pkg/transformers/bite/model.go
+++ b/pkg/transformers/bite/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite
diff --git a/pkg/transformers/bite/repository.go b/pkg/transformers/bite/repository.go
index a816bfc2..9591bcf8 100644
--- a/pkg/transformers/bite/repository.go
+++ b/pkg/transformers/bite/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite
diff --git a/pkg/transformers/bite/repository_test.go b/pkg/transformers/bite/repository_test.go
index c8d48f68..406e9c08 100644
--- a/pkg/transformers/bite/repository_test.go
+++ b/pkg/transformers/bite/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package bite_test
diff --git a/pkg/transformers/cat_file/chop_lump/chop_lump_suite_test.go b/pkg/transformers/cat_file/chop_lump/chop_lump_suite_test.go
index d39013e7..8bd2695d 100644
--- a/pkg/transformers/cat_file/chop_lump/chop_lump_suite_test.go
+++ b/pkg/transformers/cat_file/chop_lump/chop_lump_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package chop_lump_test
diff --git a/pkg/transformers/cat_file/chop_lump/config.go b/pkg/transformers/cat_file/chop_lump/config.go
index cf2d33f4..01c32106 100644
--- a/pkg/transformers/cat_file/chop_lump/config.go
+++ b/pkg/transformers/cat_file/chop_lump/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package chop_lump
diff --git a/pkg/transformers/cat_file/chop_lump/converter.go b/pkg/transformers/cat_file/chop_lump/converter.go
index bb60d5c0..ca64a0ec 100644
--- a/pkg/transformers/cat_file/chop_lump/converter.go
+++ b/pkg/transformers/cat_file/chop_lump/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package chop_lump
diff --git a/pkg/transformers/cat_file/chop_lump/converter_test.go b/pkg/transformers/cat_file/chop_lump/converter_test.go
index 81858d14..7f0f0da8 100644
--- a/pkg/transformers/cat_file/chop_lump/converter_test.go
+++ b/pkg/transformers/cat_file/chop_lump/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package chop_lump_test
diff --git a/pkg/transformers/cat_file/chop_lump/model.go b/pkg/transformers/cat_file/chop_lump/model.go
index 35df759f..ada429ce 100644
--- a/pkg/transformers/cat_file/chop_lump/model.go
+++ b/pkg/transformers/cat_file/chop_lump/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package chop_lump
diff --git a/pkg/transformers/cat_file/chop_lump/repository.go b/pkg/transformers/cat_file/chop_lump/repository.go
index 32bd20fd..52656bc8 100644
--- a/pkg/transformers/cat_file/chop_lump/repository.go
+++ b/pkg/transformers/cat_file/chop_lump/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package chop_lump
diff --git a/pkg/transformers/cat_file/chop_lump/repository_test.go b/pkg/transformers/cat_file/chop_lump/repository_test.go
index 41041f49..eade438e 100644
--- a/pkg/transformers/cat_file/chop_lump/repository_test.go
+++ b/pkg/transformers/cat_file/chop_lump/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package chop_lump_test
diff --git a/pkg/transformers/cat_file/flip/config.go b/pkg/transformers/cat_file/flip/config.go
index da68df8b..f8401d2d 100644
--- a/pkg/transformers/cat_file/flip/config.go
+++ b/pkg/transformers/cat_file/flip/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip
diff --git a/pkg/transformers/cat_file/flip/converter.go b/pkg/transformers/cat_file/flip/converter.go
index aa73bf55..efa8a517 100644
--- a/pkg/transformers/cat_file/flip/converter.go
+++ b/pkg/transformers/cat_file/flip/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip
diff --git a/pkg/transformers/cat_file/flip/converter_test.go b/pkg/transformers/cat_file/flip/converter_test.go
index 10f75d23..dd73dc53 100644
--- a/pkg/transformers/cat_file/flip/converter_test.go
+++ b/pkg/transformers/cat_file/flip/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_test
diff --git a/pkg/transformers/cat_file/flip/flip_suite_test.go b/pkg/transformers/cat_file/flip/flip_suite_test.go
index 9be529c5..83a58761 100644
--- a/pkg/transformers/cat_file/flip/flip_suite_test.go
+++ b/pkg/transformers/cat_file/flip/flip_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_test
diff --git a/pkg/transformers/cat_file/flip/model.go b/pkg/transformers/cat_file/flip/model.go
index 88150e2b..31dcdaa8 100644
--- a/pkg/transformers/cat_file/flip/model.go
+++ b/pkg/transformers/cat_file/flip/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip
diff --git a/pkg/transformers/cat_file/flip/repository.go b/pkg/transformers/cat_file/flip/repository.go
index 0cf9ab16..ac6bc9d4 100644
--- a/pkg/transformers/cat_file/flip/repository.go
+++ b/pkg/transformers/cat_file/flip/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip
diff --git a/pkg/transformers/cat_file/flip/repository_test.go b/pkg/transformers/cat_file/flip/repository_test.go
index 8dfe6027..fd345ff1 100644
--- a/pkg/transformers/cat_file/flip/repository_test.go
+++ b/pkg/transformers/cat_file/flip/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_test
diff --git a/pkg/transformers/cat_file/pit_vow/config.go b/pkg/transformers/cat_file/pit_vow/config.go
index b06b1cad..4db102a5 100644
--- a/pkg/transformers/cat_file/pit_vow/config.go
+++ b/pkg/transformers/cat_file/pit_vow/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package pit_vow
diff --git a/pkg/transformers/cat_file/pit_vow/converter.go b/pkg/transformers/cat_file/pit_vow/converter.go
index 2b62e670..ad35e4a9 100644
--- a/pkg/transformers/cat_file/pit_vow/converter.go
+++ b/pkg/transformers/cat_file/pit_vow/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package pit_vow
diff --git a/pkg/transformers/cat_file/pit_vow/converter_test.go b/pkg/transformers/cat_file/pit_vow/converter_test.go
index 062f2623..6ccf1152 100644
--- a/pkg/transformers/cat_file/pit_vow/converter_test.go
+++ b/pkg/transformers/cat_file/pit_vow/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package pit_vow_test
diff --git a/pkg/transformers/cat_file/pit_vow/model.go b/pkg/transformers/cat_file/pit_vow/model.go
index fdfddcc0..02539305 100644
--- a/pkg/transformers/cat_file/pit_vow/model.go
+++ b/pkg/transformers/cat_file/pit_vow/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package pit_vow
diff --git a/pkg/transformers/cat_file/pit_vow/pit_vow_suite_test.go b/pkg/transformers/cat_file/pit_vow/pit_vow_suite_test.go
index 133d7ac5..9116a813 100644
--- a/pkg/transformers/cat_file/pit_vow/pit_vow_suite_test.go
+++ b/pkg/transformers/cat_file/pit_vow/pit_vow_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package pit_vow_test
diff --git a/pkg/transformers/cat_file/pit_vow/repository.go b/pkg/transformers/cat_file/pit_vow/repository.go
index 1ca0c048..5e5932a4 100644
--- a/pkg/transformers/cat_file/pit_vow/repository.go
+++ b/pkg/transformers/cat_file/pit_vow/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package pit_vow
diff --git a/pkg/transformers/cat_file/pit_vow/repository_test.go b/pkg/transformers/cat_file/pit_vow/repository_test.go
index c7d31167..f476c820 100644
--- a/pkg/transformers/cat_file/pit_vow/repository_test.go
+++ b/pkg/transformers/cat_file/pit_vow/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package pit_vow_test
diff --git a/pkg/transformers/deal/config.go b/pkg/transformers/deal/config.go
index 43f232ee..f9f77f77 100644
--- a/pkg/transformers/deal/config.go
+++ b/pkg/transformers/deal/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package deal
diff --git a/pkg/transformers/deal/converter.go b/pkg/transformers/deal/converter.go
index 2a7695d7..d9545b21 100644
--- a/pkg/transformers/deal/converter.go
+++ b/pkg/transformers/deal/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package deal
diff --git a/pkg/transformers/deal/converter_test.go b/pkg/transformers/deal/converter_test.go
index 8de0b58b..b2284aed 100644
--- a/pkg/transformers/deal/converter_test.go
+++ b/pkg/transformers/deal/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package deal_test
diff --git a/pkg/transformers/deal/model.go b/pkg/transformers/deal/model.go
index cbfb194d..fe0210f6 100644
--- a/pkg/transformers/deal/model.go
+++ b/pkg/transformers/deal/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package deal
diff --git a/pkg/transformers/deal/repository.go b/pkg/transformers/deal/repository.go
index 03e229c7..4c2d1451 100644
--- a/pkg/transformers/deal/repository.go
+++ b/pkg/transformers/deal/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package deal
diff --git a/pkg/transformers/deal/repository_test.go b/pkg/transformers/deal/repository_test.go
index 2e3f02b0..96a31685 100644
--- a/pkg/transformers/deal/repository_test.go
+++ b/pkg/transformers/deal/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package deal_test
diff --git a/pkg/transformers/dent/config.go b/pkg/transformers/dent/config.go
index 681dbf43..c6703946 100644
--- a/pkg/transformers/dent/config.go
+++ b/pkg/transformers/dent/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package dent
diff --git a/pkg/transformers/dent/converter.go b/pkg/transformers/dent/converter.go
index 75ac93b3..69c1a9fe 100644
--- a/pkg/transformers/dent/converter.go
+++ b/pkg/transformers/dent/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package dent
diff --git a/pkg/transformers/dent/converter_test.go b/pkg/transformers/dent/converter_test.go
index 9d005735..0a68fd9b 100644
--- a/pkg/transformers/dent/converter_test.go
+++ b/pkg/transformers/dent/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package dent_test
diff --git a/pkg/transformers/dent/model.go b/pkg/transformers/dent/model.go
index 7f5bdfc1..24f038ac 100644
--- a/pkg/transformers/dent/model.go
+++ b/pkg/transformers/dent/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package dent
diff --git a/pkg/transformers/dent/repository.go b/pkg/transformers/dent/repository.go
index 018711da..45fa5593 100644
--- a/pkg/transformers/dent/repository.go
+++ b/pkg/transformers/dent/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package dent
diff --git a/pkg/transformers/dent/repository_test.go b/pkg/transformers/dent/repository_test.go
index b667228a..4e075f4b 100644
--- a/pkg/transformers/dent/repository_test.go
+++ b/pkg/transformers/dent/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package dent_test
diff --git a/pkg/transformers/drip_drip/config.go b/pkg/transformers/drip_drip/config.go
index 92f3a61f..6ad1921f 100644
--- a/pkg/transformers/drip_drip/config.go
+++ b/pkg/transformers/drip_drip/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package drip_drip
diff --git a/pkg/transformers/drip_drip/converter.go b/pkg/transformers/drip_drip/converter.go
index 0b36e3ef..a50d9126 100644
--- a/pkg/transformers/drip_drip/converter.go
+++ b/pkg/transformers/drip_drip/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package drip_drip
diff --git a/pkg/transformers/drip_drip/converter_test.go b/pkg/transformers/drip_drip/converter_test.go
index b16468b1..faeb9308 100644
--- a/pkg/transformers/drip_drip/converter_test.go
+++ b/pkg/transformers/drip_drip/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package drip_drip_test
diff --git a/pkg/transformers/drip_drip/drip_drip_suite_test.go b/pkg/transformers/drip_drip/drip_drip_suite_test.go
index 6d0ee7d7..ec70dc7e 100644
--- a/pkg/transformers/drip_drip/drip_drip_suite_test.go
+++ b/pkg/transformers/drip_drip/drip_drip_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package drip_drip_test
diff --git a/pkg/transformers/drip_drip/model.go b/pkg/transformers/drip_drip/model.go
index f6cc1522..4e7b19ee 100644
--- a/pkg/transformers/drip_drip/model.go
+++ b/pkg/transformers/drip_drip/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package drip_drip
diff --git a/pkg/transformers/drip_drip/repository.go b/pkg/transformers/drip_drip/repository.go
index e28a3748..c7631f01 100644
--- a/pkg/transformers/drip_drip/repository.go
+++ b/pkg/transformers/drip_drip/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package drip_drip
diff --git a/pkg/transformers/drip_drip/repository_test.go b/pkg/transformers/drip_drip/repository_test.go
index 50646855..6dbed2cc 100644
--- a/pkg/transformers/drip_drip/repository_test.go
+++ b/pkg/transformers/drip_drip/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package drip_drip_test
diff --git a/pkg/transformers/drip_file/ilk/config.go b/pkg/transformers/drip_file/ilk/config.go
index 95642b49..1ada59ba 100644
--- a/pkg/transformers/drip_file/ilk/config.go
+++ b/pkg/transformers/drip_file/ilk/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/drip_file/ilk/converter.go b/pkg/transformers/drip_file/ilk/converter.go
index 19f348e8..adfb2f3d 100644
--- a/pkg/transformers/drip_file/ilk/converter.go
+++ b/pkg/transformers/drip_file/ilk/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/drip_file/ilk/converter_test.go b/pkg/transformers/drip_file/ilk/converter_test.go
index 7d60ddc5..7af73627 100644
--- a/pkg/transformers/drip_file/ilk/converter_test.go
+++ b/pkg/transformers/drip_file/ilk/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk_test
diff --git a/pkg/transformers/drip_file/ilk/ilk_suite_test.go b/pkg/transformers/drip_file/ilk/ilk_suite_test.go
index 4327892d..469bede6 100644
--- a/pkg/transformers/drip_file/ilk/ilk_suite_test.go
+++ b/pkg/transformers/drip_file/ilk/ilk_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk_test
diff --git a/pkg/transformers/drip_file/ilk/model.go b/pkg/transformers/drip_file/ilk/model.go
index 3e4ce8e6..f2e6fdb8 100644
--- a/pkg/transformers/drip_file/ilk/model.go
+++ b/pkg/transformers/drip_file/ilk/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/drip_file/ilk/repository.go b/pkg/transformers/drip_file/ilk/repository.go
index c986a3d0..136d0e44 100644
--- a/pkg/transformers/drip_file/ilk/repository.go
+++ b/pkg/transformers/drip_file/ilk/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/drip_file/ilk/repository_test.go b/pkg/transformers/drip_file/ilk/repository_test.go
index 8dbada31..1695f17c 100644
--- a/pkg/transformers/drip_file/ilk/repository_test.go
+++ b/pkg/transformers/drip_file/ilk/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk_test
diff --git a/pkg/transformers/drip_file/repo/config.go b/pkg/transformers/drip_file/repo/config.go
index 595e4f7c..ecbf0e3f 100644
--- a/pkg/transformers/drip_file/repo/config.go
+++ b/pkg/transformers/drip_file/repo/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package repo
diff --git a/pkg/transformers/drip_file/repo/converter.go b/pkg/transformers/drip_file/repo/converter.go
index ba4aa775..0c851bc7 100644
--- a/pkg/transformers/drip_file/repo/converter.go
+++ b/pkg/transformers/drip_file/repo/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package repo
diff --git a/pkg/transformers/drip_file/repo/converter_test.go b/pkg/transformers/drip_file/repo/converter_test.go
index f2c9d223..ae4e2144 100644
--- a/pkg/transformers/drip_file/repo/converter_test.go
+++ b/pkg/transformers/drip_file/repo/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package repo_test
diff --git a/pkg/transformers/drip_file/repo/model.go b/pkg/transformers/drip_file/repo/model.go
index 476617d6..cb5da51e 100644
--- a/pkg/transformers/drip_file/repo/model.go
+++ b/pkg/transformers/drip_file/repo/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package repo
diff --git a/pkg/transformers/drip_file/repo/repo_suite_test.go b/pkg/transformers/drip_file/repo/repo_suite_test.go
index ed554b89..965d83d8 100644
--- a/pkg/transformers/drip_file/repo/repo_suite_test.go
+++ b/pkg/transformers/drip_file/repo/repo_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package repo_test
diff --git a/pkg/transformers/drip_file/repo/repository.go b/pkg/transformers/drip_file/repo/repository.go
index fab8ade4..bc910199 100644
--- a/pkg/transformers/drip_file/repo/repository.go
+++ b/pkg/transformers/drip_file/repo/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package repo
diff --git a/pkg/transformers/drip_file/repo/repository_test.go b/pkg/transformers/drip_file/repo/repository_test.go
index e8614b61..5f4c021e 100644
--- a/pkg/transformers/drip_file/repo/repository_test.go
+++ b/pkg/transformers/drip_file/repo/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package repo_test
diff --git a/pkg/transformers/drip_file/vow/config.go b/pkg/transformers/drip_file/vow/config.go
index 39d66eb2..e296bb09 100644
--- a/pkg/transformers/drip_file/vow/config.go
+++ b/pkg/transformers/drip_file/vow/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow
diff --git a/pkg/transformers/drip_file/vow/converter.go b/pkg/transformers/drip_file/vow/converter.go
index dac76194..d1a47d7f 100644
--- a/pkg/transformers/drip_file/vow/converter.go
+++ b/pkg/transformers/drip_file/vow/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow
diff --git a/pkg/transformers/drip_file/vow/converter_test.go b/pkg/transformers/drip_file/vow/converter_test.go
index 8678b597..370dd575 100644
--- a/pkg/transformers/drip_file/vow/converter_test.go
+++ b/pkg/transformers/drip_file/vow/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_test
diff --git a/pkg/transformers/drip_file/vow/model.go b/pkg/transformers/drip_file/vow/model.go
index f95cace1..1e0cbd9c 100644
--- a/pkg/transformers/drip_file/vow/model.go
+++ b/pkg/transformers/drip_file/vow/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow
diff --git a/pkg/transformers/drip_file/vow/repository.go b/pkg/transformers/drip_file/vow/repository.go
index c6b1a848..c4a9ccc4 100644
--- a/pkg/transformers/drip_file/vow/repository.go
+++ b/pkg/transformers/drip_file/vow/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow
diff --git a/pkg/transformers/drip_file/vow/repository_test.go b/pkg/transformers/drip_file/vow/repository_test.go
index 71e8cd07..067e0cad 100644
--- a/pkg/transformers/drip_file/vow/repository_test.go
+++ b/pkg/transformers/drip_file/vow/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_test
diff --git a/pkg/transformers/drip_file/vow/vow_suite_test.go b/pkg/transformers/drip_file/vow/vow_suite_test.go
index 7fff6f73..fc8a56b1 100644
--- a/pkg/transformers/drip_file/vow/vow_suite_test.go
+++ b/pkg/transformers/drip_file/vow/vow_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_test
diff --git a/pkg/transformers/factories/converter.go b/pkg/transformers/factories/converter.go
index 458b4388..1d46a048 100644
--- a/pkg/transformers/factories/converter.go
+++ b/pkg/transformers/factories/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package factories
diff --git a/pkg/transformers/factories/log_note_converter.go b/pkg/transformers/factories/log_note_converter.go
index 52e994da..646ad13a 100644
--- a/pkg/transformers/factories/log_note_converter.go
+++ b/pkg/transformers/factories/log_note_converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package factories
diff --git a/pkg/transformers/factories/log_note_transformer.go b/pkg/transformers/factories/log_note_transformer.go
index 6ae63f4b..3bc8e29b 100644
--- a/pkg/transformers/factories/log_note_transformer.go
+++ b/pkg/transformers/factories/log_note_transformer.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package factories
diff --git a/pkg/transformers/factories/log_note_transformer_test.go b/pkg/transformers/factories/log_note_transformer_test.go
index 678c9879..ef0f9524 100644
--- a/pkg/transformers/factories/log_note_transformer_test.go
+++ b/pkg/transformers/factories/log_note_transformer_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package factories_test
diff --git a/pkg/transformers/factories/repository.go b/pkg/transformers/factories/repository.go
index 0ddc9274..ed21d955 100644
--- a/pkg/transformers/factories/repository.go
+++ b/pkg/transformers/factories/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package factories
diff --git a/pkg/transformers/factories/transformer.go b/pkg/transformers/factories/transformer.go
index 5b164814..e3307589 100644
--- a/pkg/transformers/factories/transformer.go
+++ b/pkg/transformers/factories/transformer.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package factories
diff --git a/pkg/transformers/factories/transformer_test.go b/pkg/transformers/factories/transformer_test.go
index 32d85880..2cb9b21d 100644
--- a/pkg/transformers/factories/transformer_test.go
+++ b/pkg/transformers/factories/transformer_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package factories_test
diff --git a/pkg/transformers/flap_kick/config.go b/pkg/transformers/flap_kick/config.go
index afac5db2..70c5b7c9 100644
--- a/pkg/transformers/flap_kick/config.go
+++ b/pkg/transformers/flap_kick/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick
diff --git a/pkg/transformers/flap_kick/converter.go b/pkg/transformers/flap_kick/converter.go
index d5d74865..811d0495 100644
--- a/pkg/transformers/flap_kick/converter.go
+++ b/pkg/transformers/flap_kick/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick
diff --git a/pkg/transformers/flap_kick/converter_test.go b/pkg/transformers/flap_kick/converter_test.go
index 237ce910..b83f8a31 100644
--- a/pkg/transformers/flap_kick/converter_test.go
+++ b/pkg/transformers/flap_kick/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick_test
diff --git a/pkg/transformers/flap_kick/entity.go b/pkg/transformers/flap_kick/entity.go
index fd95bcb2..5f680b78 100644
--- a/pkg/transformers/flap_kick/entity.go
+++ b/pkg/transformers/flap_kick/entity.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick
diff --git a/pkg/transformers/flap_kick/flap_kick_suite_test.go b/pkg/transformers/flap_kick/flap_kick_suite_test.go
index 0d6ba9f0..7925e9fe 100644
--- a/pkg/transformers/flap_kick/flap_kick_suite_test.go
+++ b/pkg/transformers/flap_kick/flap_kick_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick_test
diff --git a/pkg/transformers/flap_kick/model.go b/pkg/transformers/flap_kick/model.go
index b50c8404..7c7635e4 100644
--- a/pkg/transformers/flap_kick/model.go
+++ b/pkg/transformers/flap_kick/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick
diff --git a/pkg/transformers/flap_kick/repository.go b/pkg/transformers/flap_kick/repository.go
index ed2b95ae..6ea7f6e0 100644
--- a/pkg/transformers/flap_kick/repository.go
+++ b/pkg/transformers/flap_kick/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick
diff --git a/pkg/transformers/flap_kick/repository_test.go b/pkg/transformers/flap_kick/repository_test.go
index 2b401cfd..3c38b246 100644
--- a/pkg/transformers/flap_kick/repository_test.go
+++ b/pkg/transformers/flap_kick/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flap_kick_test
diff --git a/pkg/transformers/flip_kick/config.go b/pkg/transformers/flip_kick/config.go
index f83f95b9..7fa8d908 100644
--- a/pkg/transformers/flip_kick/config.go
+++ b/pkg/transformers/flip_kick/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick
diff --git a/pkg/transformers/flip_kick/converter.go b/pkg/transformers/flip_kick/converter.go
index cf0a0a87..93ba551b 100644
--- a/pkg/transformers/flip_kick/converter.go
+++ b/pkg/transformers/flip_kick/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick
diff --git a/pkg/transformers/flip_kick/converter_test.go b/pkg/transformers/flip_kick/converter_test.go
index 466bf6bc..a12c4006 100644
--- a/pkg/transformers/flip_kick/converter_test.go
+++ b/pkg/transformers/flip_kick/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick_test
diff --git a/pkg/transformers/flip_kick/entity.go b/pkg/transformers/flip_kick/entity.go
index 0d11bc4a..057225eb 100644
--- a/pkg/transformers/flip_kick/entity.go
+++ b/pkg/transformers/flip_kick/entity.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick
diff --git a/pkg/transformers/flip_kick/flip_kick_suite_test.go b/pkg/transformers/flip_kick/flip_kick_suite_test.go
index ce7e68f1..b813aef9 100644
--- a/pkg/transformers/flip_kick/flip_kick_suite_test.go
+++ b/pkg/transformers/flip_kick/flip_kick_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick
diff --git a/pkg/transformers/flip_kick/model.go b/pkg/transformers/flip_kick/model.go
index 0d1ae2f5..bc817886 100644
--- a/pkg/transformers/flip_kick/model.go
+++ b/pkg/transformers/flip_kick/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick
diff --git a/pkg/transformers/flip_kick/repository.go b/pkg/transformers/flip_kick/repository.go
index f4073b87..5197685b 100644
--- a/pkg/transformers/flip_kick/repository.go
+++ b/pkg/transformers/flip_kick/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick
diff --git a/pkg/transformers/flip_kick/repository_test.go b/pkg/transformers/flip_kick/repository_test.go
index 6befc361..9d9d42f8 100644
--- a/pkg/transformers/flip_kick/repository_test.go
+++ b/pkg/transformers/flip_kick/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flip_kick_test
diff --git a/pkg/transformers/flop_kick/config.go b/pkg/transformers/flop_kick/config.go
index 860a7647..5356dbe3 100644
--- a/pkg/transformers/flop_kick/config.go
+++ b/pkg/transformers/flop_kick/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flop_kick
diff --git a/pkg/transformers/flop_kick/converter.go b/pkg/transformers/flop_kick/converter.go
index d36ca3b4..412a7e4d 100644
--- a/pkg/transformers/flop_kick/converter.go
+++ b/pkg/transformers/flop_kick/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flop_kick
diff --git a/pkg/transformers/flop_kick/converter_test.go b/pkg/transformers/flop_kick/converter_test.go
index 7f1af4f7..ee9faf3c 100644
--- a/pkg/transformers/flop_kick/converter_test.go
+++ b/pkg/transformers/flop_kick/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flop_kick_test
diff --git a/pkg/transformers/flop_kick/entity.go b/pkg/transformers/flop_kick/entity.go
index bf2e1f0d..3a598288 100644
--- a/pkg/transformers/flop_kick/entity.go
+++ b/pkg/transformers/flop_kick/entity.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flop_kick
diff --git a/pkg/transformers/flop_kick/model.go b/pkg/transformers/flop_kick/model.go
index d918c0e1..d78547cf 100644
--- a/pkg/transformers/flop_kick/model.go
+++ b/pkg/transformers/flop_kick/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flop_kick
diff --git a/pkg/transformers/flop_kick/repository.go b/pkg/transformers/flop_kick/repository.go
index 910f0dec..d6210330 100644
--- a/pkg/transformers/flop_kick/repository.go
+++ b/pkg/transformers/flop_kick/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flop_kick
diff --git a/pkg/transformers/flop_kick/repository_test.go b/pkg/transformers/flop_kick/repository_test.go
index 8d5a8351..cf2990ce 100644
--- a/pkg/transformers/flop_kick/repository_test.go
+++ b/pkg/transformers/flop_kick/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package flop_kick_test
diff --git a/pkg/transformers/frob/config.go b/pkg/transformers/frob/config.go
index d740a37c..5c91231a 100644
--- a/pkg/transformers/frob/config.go
+++ b/pkg/transformers/frob/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob
diff --git a/pkg/transformers/frob/converter.go b/pkg/transformers/frob/converter.go
index 00013cab..8b765b91 100644
--- a/pkg/transformers/frob/converter.go
+++ b/pkg/transformers/frob/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob
diff --git a/pkg/transformers/frob/converter_test.go b/pkg/transformers/frob/converter_test.go
index ce235350..75b7ccf1 100644
--- a/pkg/transformers/frob/converter_test.go
+++ b/pkg/transformers/frob/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob_test
diff --git a/pkg/transformers/frob/entity.go b/pkg/transformers/frob/entity.go
index d33eb49d..ddd9fcc0 100644
--- a/pkg/transformers/frob/entity.go
+++ b/pkg/transformers/frob/entity.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob
diff --git a/pkg/transformers/frob/frob_suite_test.go b/pkg/transformers/frob/frob_suite_test.go
index 126b1371..16b3b57a 100644
--- a/pkg/transformers/frob/frob_suite_test.go
+++ b/pkg/transformers/frob/frob_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob_test
diff --git a/pkg/transformers/frob/model.go b/pkg/transformers/frob/model.go
index eef52833..86acc6a9 100644
--- a/pkg/transformers/frob/model.go
+++ b/pkg/transformers/frob/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob
diff --git a/pkg/transformers/frob/repository.go b/pkg/transformers/frob/repository.go
index c857013a..5e336c0c 100644
--- a/pkg/transformers/frob/repository.go
+++ b/pkg/transformers/frob/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob
diff --git a/pkg/transformers/frob/repository_test.go b/pkg/transformers/frob/repository_test.go
index 36c6036a..ae2b0b54 100644
--- a/pkg/transformers/frob/repository_test.go
+++ b/pkg/transformers/frob/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package frob_test
diff --git a/pkg/transformers/integration_tests/bite.go b/pkg/transformers/integration_tests/bite.go
index 57225719..708a98eb 100644
--- a/pkg/transformers/integration_tests/bite.go
+++ b/pkg/transformers/integration_tests/bite.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/cat_file.go b/pkg/transformers/integration_tests/cat_file.go
index bf75b730..bc9a2358 100644
--- a/pkg/transformers/integration_tests/cat_file.go
+++ b/pkg/transformers/integration_tests/cat_file.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/deal.go b/pkg/transformers/integration_tests/deal.go
index dda8c3f8..cdaf26de 100644
--- a/pkg/transformers/integration_tests/deal.go
+++ b/pkg/transformers/integration_tests/deal.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/drip_drip.go b/pkg/transformers/integration_tests/drip_drip.go
index dce5fe32..0ca6e487 100644
--- a/pkg/transformers/integration_tests/drip_drip.go
+++ b/pkg/transformers/integration_tests/drip_drip.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/drip_file_vow.go b/pkg/transformers/integration_tests/drip_file_vow.go
index f3ebb494..841fc154 100644
--- a/pkg/transformers/integration_tests/drip_file_vow.go
+++ b/pkg/transformers/integration_tests/drip_file_vow.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/flap_kick.go b/pkg/transformers/integration_tests/flap_kick.go
index ef270b5e..0894c4a8 100644
--- a/pkg/transformers/integration_tests/flap_kick.go
+++ b/pkg/transformers/integration_tests/flap_kick.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/flip_kick.go b/pkg/transformers/integration_tests/flip_kick.go
index fa86e285..f4e4cd3f 100644
--- a/pkg/transformers/integration_tests/flip_kick.go
+++ b/pkg/transformers/integration_tests/flip_kick.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/flop_kick.go b/pkg/transformers/integration_tests/flop_kick.go
index 66537139..b6ee9ff0 100644
--- a/pkg/transformers/integration_tests/flop_kick.go
+++ b/pkg/transformers/integration_tests/flop_kick.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/frob.go b/pkg/transformers/integration_tests/frob.go
index 85697466..b3f01742 100644
--- a/pkg/transformers/integration_tests/frob.go
+++ b/pkg/transformers/integration_tests/frob.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/helpers.go b/pkg/transformers/integration_tests/helpers.go
index f6d00278..8d7681d3 100644
--- a/pkg/transformers/integration_tests/helpers.go
+++ b/pkg/transformers/integration_tests/helpers.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
@@ -26,6 +28,8 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
)
+var ipc string
+
func getClients(ipc string) (client.RpcClient, *ethclient.Client, error) {
raw, err := rpc.Dial(ipc)
if err != nil {
diff --git a/pkg/transformers/integration_tests/integration_tests_suite_test.go b/pkg/transformers/integration_tests/integration_tests_suite_test.go
index 454c0798..301e779e 100644
--- a/pkg/transformers/integration_tests/integration_tests_suite_test.go
+++ b/pkg/transformers/integration_tests/integration_tests_suite_test.go
@@ -10,8 +10,6 @@ import (
"io/ioutil"
)
-var ipc string
-
func TestIntegrationTests(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "IntegrationTests Suite")
diff --git a/pkg/transformers/integration_tests/pit_file_debt_ceiling.go b/pkg/transformers/integration_tests/pit_file_debt_ceiling.go
index 38dfe2ae..9caecf39 100644
--- a/pkg/transformers/integration_tests/pit_file_debt_ceiling.go
+++ b/pkg/transformers/integration_tests/pit_file_debt_ceiling.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/pit_file_ilk.go b/pkg/transformers/integration_tests/pit_file_ilk.go
index a5e0ac88..5dfca2e6 100644
--- a/pkg/transformers/integration_tests/pit_file_ilk.go
+++ b/pkg/transformers/integration_tests/pit_file_ilk.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/price_feeds.go b/pkg/transformers/integration_tests/price_feeds.go
index e36baf1c..3fac7d8f 100644
--- a/pkg/transformers/integration_tests/price_feeds.go
+++ b/pkg/transformers/integration_tests/price_feeds.go
@@ -1,16 +1,4 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB // Copyright © 2018 Vulcanize // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/tend.go b/pkg/transformers/integration_tests/tend.go
index 83398ccb..3c1afc24 100644
--- a/pkg/transformers/integration_tests/tend.go
+++ b/pkg/transformers/integration_tests/tend.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vat_flux.go b/pkg/transformers/integration_tests/vat_flux.go
index c379c07f..6f46e2ee 100644
--- a/pkg/transformers/integration_tests/vat_flux.go
+++ b/pkg/transformers/integration_tests/vat_flux.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vat_fold.go b/pkg/transformers/integration_tests/vat_fold.go
index eb60e7e6..8357f950 100644
--- a/pkg/transformers/integration_tests/vat_fold.go
+++ b/pkg/transformers/integration_tests/vat_fold.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vat_grab.go b/pkg/transformers/integration_tests/vat_grab.go
index 77c4c3d5..b29f1e7a 100644
--- a/pkg/transformers/integration_tests/vat_grab.go
+++ b/pkg/transformers/integration_tests/vat_grab.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vat_heal.go b/pkg/transformers/integration_tests/vat_heal.go
index 93393e44..05f7dce3 100644
--- a/pkg/transformers/integration_tests/vat_heal.go
+++ b/pkg/transformers/integration_tests/vat_heal.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vat_init.go b/pkg/transformers/integration_tests/vat_init.go
index 47a24388..bbc0e47a 100644
--- a/pkg/transformers/integration_tests/vat_init.go
+++ b/pkg/transformers/integration_tests/vat_init.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vat_move.go b/pkg/transformers/integration_tests/vat_move.go
index 5ffa97f4..fafab17c 100644
--- a/pkg/transformers/integration_tests/vat_move.go
+++ b/pkg/transformers/integration_tests/vat_move.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vat_tune.go b/pkg/transformers/integration_tests/vat_tune.go
index 6f81cdf9..ba443847 100644
--- a/pkg/transformers/integration_tests/vat_tune.go
+++ b/pkg/transformers/integration_tests/vat_tune.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/integration_tests/vow_flog.go b/pkg/transformers/integration_tests/vow_flog.go
index c7c39359..08d6bfcd 100644
--- a/pkg/transformers/integration_tests/vow_flog.go
+++ b/pkg/transformers/integration_tests/vow_flog.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package integration_tests
diff --git a/pkg/transformers/pit_file/debt_ceiling/config.go b/pkg/transformers/pit_file/debt_ceiling/config.go
index d76d2da0..70ab91fc 100644
--- a/pkg/transformers/pit_file/debt_ceiling/config.go
+++ b/pkg/transformers/pit_file/debt_ceiling/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package debt_ceiling
diff --git a/pkg/transformers/pit_file/debt_ceiling/converter.go b/pkg/transformers/pit_file/debt_ceiling/converter.go
index e62f2b46..4a8c0f41 100644
--- a/pkg/transformers/pit_file/debt_ceiling/converter.go
+++ b/pkg/transformers/pit_file/debt_ceiling/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package debt_ceiling
diff --git a/pkg/transformers/pit_file/debt_ceiling/converter_test.go b/pkg/transformers/pit_file/debt_ceiling/converter_test.go
index 2ed70a59..1c2c7ee7 100644
--- a/pkg/transformers/pit_file/debt_ceiling/converter_test.go
+++ b/pkg/transformers/pit_file/debt_ceiling/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package debt_ceiling_test
diff --git a/pkg/transformers/pit_file/debt_ceiling/debt_ceiling_suite_test.go b/pkg/transformers/pit_file/debt_ceiling/debt_ceiling_suite_test.go
index 93ec396f..8bece7ec 100644
--- a/pkg/transformers/pit_file/debt_ceiling/debt_ceiling_suite_test.go
+++ b/pkg/transformers/pit_file/debt_ceiling/debt_ceiling_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package debt_ceiling_test
diff --git a/pkg/transformers/pit_file/debt_ceiling/model.go b/pkg/transformers/pit_file/debt_ceiling/model.go
index 0de13d74..3639a3e6 100644
--- a/pkg/transformers/pit_file/debt_ceiling/model.go
+++ b/pkg/transformers/pit_file/debt_ceiling/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package debt_ceiling
diff --git a/pkg/transformers/pit_file/debt_ceiling/repository.go b/pkg/transformers/pit_file/debt_ceiling/repository.go
index f2c44c79..118f875c 100644
--- a/pkg/transformers/pit_file/debt_ceiling/repository.go
+++ b/pkg/transformers/pit_file/debt_ceiling/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package debt_ceiling
diff --git a/pkg/transformers/pit_file/debt_ceiling/repository_test.go b/pkg/transformers/pit_file/debt_ceiling/repository_test.go
index 026d0446..de06cc78 100644
--- a/pkg/transformers/pit_file/debt_ceiling/repository_test.go
+++ b/pkg/transformers/pit_file/debt_ceiling/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package debt_ceiling_test
diff --git a/pkg/transformers/pit_file/ilk/config.go b/pkg/transformers/pit_file/ilk/config.go
index 07220752..6ac0374e 100644
--- a/pkg/transformers/pit_file/ilk/config.go
+++ b/pkg/transformers/pit_file/ilk/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/pit_file/ilk/converter.go b/pkg/transformers/pit_file/ilk/converter.go
index 6001786b..b1d4a94c 100644
--- a/pkg/transformers/pit_file/ilk/converter.go
+++ b/pkg/transformers/pit_file/ilk/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/pit_file/ilk/converter_test.go b/pkg/transformers/pit_file/ilk/converter_test.go
index bdaf4cc6..3b15d50a 100644
--- a/pkg/transformers/pit_file/ilk/converter_test.go
+++ b/pkg/transformers/pit_file/ilk/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk_test
diff --git a/pkg/transformers/pit_file/ilk/ilk_suite_test.go b/pkg/transformers/pit_file/ilk/ilk_suite_test.go
index 4327892d..469bede6 100644
--- a/pkg/transformers/pit_file/ilk/ilk_suite_test.go
+++ b/pkg/transformers/pit_file/ilk/ilk_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk_test
diff --git a/pkg/transformers/pit_file/ilk/model.go b/pkg/transformers/pit_file/ilk/model.go
index f861451a..7c73ab98 100644
--- a/pkg/transformers/pit_file/ilk/model.go
+++ b/pkg/transformers/pit_file/ilk/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/pit_file/ilk/repository.go b/pkg/transformers/pit_file/ilk/repository.go
index cdb01d1b..0ec9860d 100644
--- a/pkg/transformers/pit_file/ilk/repository.go
+++ b/pkg/transformers/pit_file/ilk/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk
diff --git a/pkg/transformers/pit_file/ilk/repository_test.go b/pkg/transformers/pit_file/ilk/repository_test.go
index 6521ba28..99ea098e 100644
--- a/pkg/transformers/pit_file/ilk/repository_test.go
+++ b/pkg/transformers/pit_file/ilk/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package ilk_test
diff --git a/pkg/transformers/price_feeds/config.go b/pkg/transformers/price_feeds/config.go
index 1c9b168b..bff9a8ec 100644
--- a/pkg/transformers/price_feeds/config.go
+++ b/pkg/transformers/price_feeds/config.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds
diff --git a/pkg/transformers/price_feeds/constants.go b/pkg/transformers/price_feeds/constants.go
index 9a407c42..88df5115 100644
--- a/pkg/transformers/price_feeds/constants.go
+++ b/pkg/transformers/price_feeds/constants.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds
diff --git a/pkg/transformers/price_feeds/converter.go b/pkg/transformers/price_feeds/converter.go
index cd14573a..c36e4c46 100644
--- a/pkg/transformers/price_feeds/converter.go
+++ b/pkg/transformers/price_feeds/converter.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds
diff --git a/pkg/transformers/price_feeds/converter_test.go b/pkg/transformers/price_feeds/converter_test.go
index c9a0df77..36931d21 100644
--- a/pkg/transformers/price_feeds/converter_test.go
+++ b/pkg/transformers/price_feeds/converter_test.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds_test
diff --git a/pkg/transformers/price_feeds/model.go b/pkg/transformers/price_feeds/model.go
index 6fad860b..f21d75f5 100644
--- a/pkg/transformers/price_feeds/model.go
+++ b/pkg/transformers/price_feeds/model.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds
diff --git a/pkg/transformers/price_feeds/price_feeds_suite_test.go b/pkg/transformers/price_feeds/price_feeds_suite_test.go
index c351869e..04417f29 100644
--- a/pkg/transformers/price_feeds/price_feeds_suite_test.go
+++ b/pkg/transformers/price_feeds/price_feeds_suite_test.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds_test
diff --git a/pkg/transformers/price_feeds/repository.go b/pkg/transformers/price_feeds/repository.go
index d3056d8b..3ee1fbbd 100644
--- a/pkg/transformers/price_feeds/repository.go
+++ b/pkg/transformers/price_feeds/repository.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds
diff --git a/pkg/transformers/price_feeds/repository_test.go b/pkg/transformers/price_feeds/repository_test.go
index f58aef0d..41c86359 100644
--- a/pkg/transformers/price_feeds/repository_test.go
+++ b/pkg/transformers/price_feeds/repository_test.go
@@ -1,16 +1,18 @@
+// VulcanizeDB
// Copyright © 2018 Vulcanize
-//
-// 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.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package price_feeds_test
diff --git a/pkg/transformers/shared/constants/event_signature_generator.go b/pkg/transformers/shared/constants/event_signature_generator.go
index ed9e1c78..aa288094 100644
--- a/pkg/transformers/shared/constants/event_signature_generator.go
+++ b/pkg/transformers/shared/constants/event_signature_generator.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package constants
diff --git a/pkg/transformers/shared/constants/event_signature_generator_test.go b/pkg/transformers/shared/constants/event_signature_generator_test.go
index a31e9d0a..54a15d85 100644
--- a/pkg/transformers/shared/constants/event_signature_generator_test.go
+++ b/pkg/transformers/shared/constants/event_signature_generator_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package constants_test
diff --git a/pkg/transformers/shared/log_chunker.go b/pkg/transformers/shared/log_chunker.go
index 26be32ef..183bb7d3 100644
--- a/pkg/transformers/shared/log_chunker.go
+++ b/pkg/transformers/shared/log_chunker.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared
diff --git a/pkg/transformers/shared/log_chunker_test.go b/pkg/transformers/shared/log_chunker_test.go
index 713ed4e1..cc75d7aa 100644
--- a/pkg/transformers/shared/log_chunker_test.go
+++ b/pkg/transformers/shared/log_chunker_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared_test
diff --git a/pkg/transformers/shared/log_fetcher.go b/pkg/transformers/shared/log_fetcher.go
index 11081a24..e786d48c 100644
--- a/pkg/transformers/shared/log_fetcher.go
+++ b/pkg/transformers/shared/log_fetcher.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared
diff --git a/pkg/transformers/shared/log_fetcher_test.go b/pkg/transformers/shared/log_fetcher_test.go
index 4a0c55fa..2c3ff75b 100644
--- a/pkg/transformers/shared/log_fetcher_test.go
+++ b/pkg/transformers/shared/log_fetcher_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared_test
diff --git a/pkg/transformers/shared/repository_utility_test.go b/pkg/transformers/shared/repository_utility_test.go
index 2699108e..b4498afb 100644
--- a/pkg/transformers/shared/repository_utility_test.go
+++ b/pkg/transformers/shared/repository_utility_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared_test
diff --git a/pkg/transformers/shared/transformer.go b/pkg/transformers/shared/transformer.go
index 0cc510d4..500afec7 100644
--- a/pkg/transformers/shared/transformer.go
+++ b/pkg/transformers/shared/transformer.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared
diff --git a/pkg/transformers/shared/utilities.go b/pkg/transformers/shared/utilities.go
index fadc865f..7ee4b5b6 100644
--- a/pkg/transformers/shared/utilities.go
+++ b/pkg/transformers/shared/utilities.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared
diff --git a/pkg/transformers/tend/config.go b/pkg/transformers/tend/config.go
index 39b049d7..8013e97d 100644
--- a/pkg/transformers/tend/config.go
+++ b/pkg/transformers/tend/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package tend
diff --git a/pkg/transformers/tend/converter.go b/pkg/transformers/tend/converter.go
index 1b49a6ca..784f87ad 100644
--- a/pkg/transformers/tend/converter.go
+++ b/pkg/transformers/tend/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package tend
diff --git a/pkg/transformers/tend/converter_test.go b/pkg/transformers/tend/converter_test.go
index ec07fec3..2ede2f08 100644
--- a/pkg/transformers/tend/converter_test.go
+++ b/pkg/transformers/tend/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package tend_test
diff --git a/pkg/transformers/tend/model.go b/pkg/transformers/tend/model.go
index 58c1d4ba..4c08ba11 100644
--- a/pkg/transformers/tend/model.go
+++ b/pkg/transformers/tend/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package tend
diff --git a/pkg/transformers/tend/repository.go b/pkg/transformers/tend/repository.go
index b4ea5475..75ff6760 100644
--- a/pkg/transformers/tend/repository.go
+++ b/pkg/transformers/tend/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package tend
diff --git a/pkg/transformers/tend/repository_test.go b/pkg/transformers/tend/repository_test.go
index 0753524f..e8d3da73 100644
--- a/pkg/transformers/tend/repository_test.go
+++ b/pkg/transformers/tend/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package tend_test
diff --git a/pkg/transformers/test_data/bite.go b/pkg/transformers/test_data/bite.go
index 670b0ad5..eb6ab6c7 100644
--- a/pkg/transformers/test_data/bite.go
+++ b/pkg/transformers/test_data/bite.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/cat_file.go b/pkg/transformers/test_data/cat_file.go
index 8cd5c556..6315cfe1 100644
--- a/pkg/transformers/test_data/cat_file.go
+++ b/pkg/transformers/test_data/cat_file.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/deal.go b/pkg/transformers/test_data/deal.go
index 65b8dfd0..ab1e64cf 100644
--- a/pkg/transformers/test_data/deal.go
+++ b/pkg/transformers/test_data/deal.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/dent.go b/pkg/transformers/test_data/dent.go
index 8365f2dc..027bf0be 100644
--- a/pkg/transformers/test_data/dent.go
+++ b/pkg/transformers/test_data/dent.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/drip_drip.go b/pkg/transformers/test_data/drip_drip.go
index ef60b4d5..53754667 100644
--- a/pkg/transformers/test_data/drip_drip.go
+++ b/pkg/transformers/test_data/drip_drip.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/drip_file.go b/pkg/transformers/test_data/drip_file.go
index 37bbc88f..ba0fe075 100644
--- a/pkg/transformers/test_data/drip_file.go
+++ b/pkg/transformers/test_data/drip_file.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/flip_kick.go b/pkg/transformers/test_data/flip_kick.go
index 83498a1d..80b7ade7 100644
--- a/pkg/transformers/test_data/flip_kick.go
+++ b/pkg/transformers/test_data/flip_kick.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/flop_kick.go b/pkg/transformers/test_data/flop_kick.go
index 870319ac..a573e271 100644
--- a/pkg/transformers/test_data/flop_kick.go
+++ b/pkg/transformers/test_data/flop_kick.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/frob.go b/pkg/transformers/test_data/frob.go
index cdaf6649..7edf187b 100644
--- a/pkg/transformers/test_data/frob.go
+++ b/pkg/transformers/test_data/frob.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/generic.go b/pkg/transformers/test_data/generic.go
index 64a59ea0..db5c8a0f 100644
--- a/pkg/transformers/test_data/generic.go
+++ b/pkg/transformers/test_data/generic.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/mocks/log_fetcher.go b/pkg/transformers/test_data/mocks/log_fetcher.go
index ff3db503..bd73276c 100644
--- a/pkg/transformers/test_data/mocks/log_fetcher.go
+++ b/pkg/transformers/test_data/mocks/log_fetcher.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package mocks
diff --git a/pkg/transformers/test_data/pit_file.go b/pkg/transformers/test_data/pit_file.go
index 3d8b1637..f798b795 100644
--- a/pkg/transformers/test_data/pit_file.go
+++ b/pkg/transformers/test_data/pit_file.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/price_feed.go b/pkg/transformers/test_data/price_feed.go
index 1be5b4e6..c9f59739 100644
--- a/pkg/transformers/test_data/price_feed.go
+++ b/pkg/transformers/test_data/price_feed.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/shared_behaviors/repository_behaviors.go b/pkg/transformers/test_data/shared_behaviors/repository_behaviors.go
index 745dcd3d..d3502760 100644
--- a/pkg/transformers/test_data/shared_behaviors/repository_behaviors.go
+++ b/pkg/transformers/test_data/shared_behaviors/repository_behaviors.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package shared_behaviors
diff --git a/pkg/transformers/test_data/tend.go b/pkg/transformers/test_data/tend.go
index 5e3a0c9c..f86df951 100644
--- a/pkg/transformers/test_data/tend.go
+++ b/pkg/transformers/test_data/tend.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/vat_flux.go b/pkg/transformers/test_data/vat_flux.go
index 4b9e6cde..2a5654e7 100644
--- a/pkg/transformers/test_data/vat_flux.go
+++ b/pkg/transformers/test_data/vat_flux.go
@@ -1,18 +1,18 @@
-/*
- * Copyright 2018 Vulcanize
- *
- * 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.
- */
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/vat_fold.go b/pkg/transformers/test_data/vat_fold.go
index 73045935..be7bf64e 100644
--- a/pkg/transformers/test_data/vat_fold.go
+++ b/pkg/transformers/test_data/vat_fold.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/vat_heal.go b/pkg/transformers/test_data/vat_heal.go
index 3679f6cc..03258b76 100644
--- a/pkg/transformers/test_data/vat_heal.go
+++ b/pkg/transformers/test_data/vat_heal.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/vat_init.go b/pkg/transformers/test_data/vat_init.go
index 17cfabf3..d26d6311 100644
--- a/pkg/transformers/test_data/vat_init.go
+++ b/pkg/transformers/test_data/vat_init.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/vat_move.go b/pkg/transformers/test_data/vat_move.go
index 9fd48c63..f7b11a91 100644
--- a/pkg/transformers/test_data/vat_move.go
+++ b/pkg/transformers/test_data/vat_move.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/vat_slip.go b/pkg/transformers/test_data/vat_slip.go
index 5fac645a..5b5efd9b 100644
--- a/pkg/transformers/test_data/vat_slip.go
+++ b/pkg/transformers/test_data/vat_slip.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/vow_flog.go b/pkg/transformers/test_data/vow_flog.go
index 427abc53..7f73cf75 100644
--- a/pkg/transformers/test_data/vow_flog.go
+++ b/pkg/transformers/test_data/vow_flog.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/test_data/wrong_types.go b/pkg/transformers/test_data/wrong_types.go
index 423c5bee..30aa69e1 100644
--- a/pkg/transformers/test_data/wrong_types.go
+++ b/pkg/transformers/test_data/wrong_types.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package test_data
diff --git a/pkg/transformers/transformers.go b/pkg/transformers/transformers.go
index 48cc3962..3e5625fb 100644
--- a/pkg/transformers/transformers.go
+++ b/pkg/transformers/transformers.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package transformers
diff --git a/pkg/transformers/vat_flux/converter.go b/pkg/transformers/vat_flux/converter.go
index 81d4c885..cb2a35eb 100644
--- a/pkg/transformers/vat_flux/converter.go
+++ b/pkg/transformers/vat_flux/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_flux
diff --git a/pkg/transformers/vat_flux/converter_test.go b/pkg/transformers/vat_flux/converter_test.go
index cd2c381b..7b8727ce 100644
--- a/pkg/transformers/vat_flux/converter_test.go
+++ b/pkg/transformers/vat_flux/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_flux_test
diff --git a/pkg/transformers/vat_flux/model.go b/pkg/transformers/vat_flux/model.go
index 6d328125..ce3e2aa2 100644
--- a/pkg/transformers/vat_flux/model.go
+++ b/pkg/transformers/vat_flux/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_flux
diff --git a/pkg/transformers/vat_flux/repository.go b/pkg/transformers/vat_flux/repository.go
index 60ae66c8..6b8af24b 100644
--- a/pkg/transformers/vat_flux/repository.go
+++ b/pkg/transformers/vat_flux/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_flux
diff --git a/pkg/transformers/vat_flux/repository_test.go b/pkg/transformers/vat_flux/repository_test.go
index a8b7ab85..fb6cfd41 100644
--- a/pkg/transformers/vat_flux/repository_test.go
+++ b/pkg/transformers/vat_flux/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_flux_test
diff --git a/pkg/transformers/vat_fold/config.go b/pkg/transformers/vat_fold/config.go
index 696061ad..f8e35c17 100644
--- a/pkg/transformers/vat_fold/config.go
+++ b/pkg/transformers/vat_fold/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_fold
diff --git a/pkg/transformers/vat_fold/converter.go b/pkg/transformers/vat_fold/converter.go
index 6fbac2f5..dbfa8a8b 100644
--- a/pkg/transformers/vat_fold/converter.go
+++ b/pkg/transformers/vat_fold/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_fold
diff --git a/pkg/transformers/vat_fold/converter_test.go b/pkg/transformers/vat_fold/converter_test.go
index dc0afc7f..9966a503 100644
--- a/pkg/transformers/vat_fold/converter_test.go
+++ b/pkg/transformers/vat_fold/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_fold_test
diff --git a/pkg/transformers/vat_fold/repository.go b/pkg/transformers/vat_fold/repository.go
index 049350cd..87aac383 100644
--- a/pkg/transformers/vat_fold/repository.go
+++ b/pkg/transformers/vat_fold/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_fold
diff --git a/pkg/transformers/vat_fold/repository_test.go b/pkg/transformers/vat_fold/repository_test.go
index fc551b37..dbd15a4d 100644
--- a/pkg/transformers/vat_fold/repository_test.go
+++ b/pkg/transformers/vat_fold/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_fold_test
diff --git a/pkg/transformers/vat_heal/config.go b/pkg/transformers/vat_heal/config.go
index ff40a8a1..4bc0831c 100644
--- a/pkg/transformers/vat_heal/config.go
+++ b/pkg/transformers/vat_heal/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_heal
diff --git a/pkg/transformers/vat_heal/converter.go b/pkg/transformers/vat_heal/converter.go
index c23dab3f..1e73e784 100644
--- a/pkg/transformers/vat_heal/converter.go
+++ b/pkg/transformers/vat_heal/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_heal
diff --git a/pkg/transformers/vat_heal/converter_test.go b/pkg/transformers/vat_heal/converter_test.go
index 1bf347ad..e4364897 100644
--- a/pkg/transformers/vat_heal/converter_test.go
+++ b/pkg/transformers/vat_heal/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_heal_test
diff --git a/pkg/transformers/vat_heal/model.go b/pkg/transformers/vat_heal/model.go
index dce7e938..675f610c 100644
--- a/pkg/transformers/vat_heal/model.go
+++ b/pkg/transformers/vat_heal/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_heal
diff --git a/pkg/transformers/vat_heal/repository.go b/pkg/transformers/vat_heal/repository.go
index c471cecb..87e14d20 100644
--- a/pkg/transformers/vat_heal/repository.go
+++ b/pkg/transformers/vat_heal/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_heal
diff --git a/pkg/transformers/vat_heal/repository_test.go b/pkg/transformers/vat_heal/repository_test.go
index d16bd9df..ff5292fe 100644
--- a/pkg/transformers/vat_heal/repository_test.go
+++ b/pkg/transformers/vat_heal/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_heal_test
diff --git a/pkg/transformers/vat_init/config.go b/pkg/transformers/vat_init/config.go
index 16954d0a..7d83c9d5 100644
--- a/pkg/transformers/vat_init/config.go
+++ b/pkg/transformers/vat_init/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_init
diff --git a/pkg/transformers/vat_init/converter.go b/pkg/transformers/vat_init/converter.go
index b4f7b337..d5efeb16 100644
--- a/pkg/transformers/vat_init/converter.go
+++ b/pkg/transformers/vat_init/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_init
diff --git a/pkg/transformers/vat_init/converter_test.go b/pkg/transformers/vat_init/converter_test.go
index 35ef0f9c..8a2fbf12 100644
--- a/pkg/transformers/vat_init/converter_test.go
+++ b/pkg/transformers/vat_init/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_init_test
diff --git a/pkg/transformers/vat_init/model.go b/pkg/transformers/vat_init/model.go
index 81376ace..a23422ad 100644
--- a/pkg/transformers/vat_init/model.go
+++ b/pkg/transformers/vat_init/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_init
diff --git a/pkg/transformers/vat_init/repository.go b/pkg/transformers/vat_init/repository.go
index 49d4eab3..f74ed468 100644
--- a/pkg/transformers/vat_init/repository.go
+++ b/pkg/transformers/vat_init/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_init
diff --git a/pkg/transformers/vat_init/repository_test.go b/pkg/transformers/vat_init/repository_test.go
index 6e505171..6b9ff3b6 100644
--- a/pkg/transformers/vat_init/repository_test.go
+++ b/pkg/transformers/vat_init/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_init_test
diff --git a/pkg/transformers/vat_init/vat_init_suite_test.go b/pkg/transformers/vat_init/vat_init_suite_test.go
index 4d5fb572..b5e75fe4 100644
--- a/pkg/transformers/vat_init/vat_init_suite_test.go
+++ b/pkg/transformers/vat_init/vat_init_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_init_test
diff --git a/pkg/transformers/vat_move/config.go b/pkg/transformers/vat_move/config.go
index e01bbef5..6f8884d3 100644
--- a/pkg/transformers/vat_move/config.go
+++ b/pkg/transformers/vat_move/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_move
diff --git a/pkg/transformers/vat_move/converter.go b/pkg/transformers/vat_move/converter.go
index a819a86e..54f22bbd 100644
--- a/pkg/transformers/vat_move/converter.go
+++ b/pkg/transformers/vat_move/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_move
diff --git a/pkg/transformers/vat_move/converter_test.go b/pkg/transformers/vat_move/converter_test.go
index bb215be0..5e3313f7 100644
--- a/pkg/transformers/vat_move/converter_test.go
+++ b/pkg/transformers/vat_move/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_move_test
diff --git a/pkg/transformers/vat_move/model.go b/pkg/transformers/vat_move/model.go
index 2ed2e909..80c37852 100644
--- a/pkg/transformers/vat_move/model.go
+++ b/pkg/transformers/vat_move/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_move
diff --git a/pkg/transformers/vat_move/repository.go b/pkg/transformers/vat_move/repository.go
index cffe70e8..dc45d4a5 100644
--- a/pkg/transformers/vat_move/repository.go
+++ b/pkg/transformers/vat_move/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_move
diff --git a/pkg/transformers/vat_move/repository_test.go b/pkg/transformers/vat_move/repository_test.go
index 179a2ee0..905559dc 100644
--- a/pkg/transformers/vat_move/repository_test.go
+++ b/pkg/transformers/vat_move/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_move_test
diff --git a/pkg/transformers/vat_move/vat_move_suite_test.go b/pkg/transformers/vat_move/vat_move_suite_test.go
index 3c3a218a..e42b8919 100644
--- a/pkg/transformers/vat_move/vat_move_suite_test.go
+++ b/pkg/transformers/vat_move/vat_move_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_move_test
diff --git a/pkg/transformers/vat_slip/converter.go b/pkg/transformers/vat_slip/converter.go
index 87f1af5f..ec380c02 100644
--- a/pkg/transformers/vat_slip/converter.go
+++ b/pkg/transformers/vat_slip/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_slip
diff --git a/pkg/transformers/vat_slip/converter_test.go b/pkg/transformers/vat_slip/converter_test.go
index db4a6940..24107eb0 100644
--- a/pkg/transformers/vat_slip/converter_test.go
+++ b/pkg/transformers/vat_slip/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_slip_test
diff --git a/pkg/transformers/vat_slip/model.go b/pkg/transformers/vat_slip/model.go
index a3d67e87..adb69417 100644
--- a/pkg/transformers/vat_slip/model.go
+++ b/pkg/transformers/vat_slip/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_slip
diff --git a/pkg/transformers/vat_slip/vat_slip_suite_test.go b/pkg/transformers/vat_slip/vat_slip_suite_test.go
index e85f3ca4..643ccd4f 100644
--- a/pkg/transformers/vat_slip/vat_slip_suite_test.go
+++ b/pkg/transformers/vat_slip/vat_slip_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vat_slip_test
diff --git a/pkg/transformers/vow_flog/config.go b/pkg/transformers/vow_flog/config.go
index ea66430c..ca32ced2 100644
--- a/pkg/transformers/vow_flog/config.go
+++ b/pkg/transformers/vow_flog/config.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_flog
diff --git a/pkg/transformers/vow_flog/converter.go b/pkg/transformers/vow_flog/converter.go
index 4e33cb03..dcabd152 100644
--- a/pkg/transformers/vow_flog/converter.go
+++ b/pkg/transformers/vow_flog/converter.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_flog
diff --git a/pkg/transformers/vow_flog/converter_test.go b/pkg/transformers/vow_flog/converter_test.go
index 895fe510..fd26d573 100644
--- a/pkg/transformers/vow_flog/converter_test.go
+++ b/pkg/transformers/vow_flog/converter_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_flog_test
diff --git a/pkg/transformers/vow_flog/model.go b/pkg/transformers/vow_flog/model.go
index 569cd92d..4fdbda8d 100644
--- a/pkg/transformers/vow_flog/model.go
+++ b/pkg/transformers/vow_flog/model.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_flog
diff --git a/pkg/transformers/vow_flog/repository.go b/pkg/transformers/vow_flog/repository.go
index c83496b4..20f06bad 100644
--- a/pkg/transformers/vow_flog/repository.go
+++ b/pkg/transformers/vow_flog/repository.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_flog
diff --git a/pkg/transformers/vow_flog/repository_test.go b/pkg/transformers/vow_flog/repository_test.go
index de6b3b94..5f843c07 100644
--- a/pkg/transformers/vow_flog/repository_test.go
+++ b/pkg/transformers/vow_flog/repository_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_flog_test
diff --git a/pkg/transformers/vow_flog/vow_flog_suite_test.go b/pkg/transformers/vow_flog/vow_flog_suite_test.go
index abb962ac..f5b602d7 100644
--- a/pkg/transformers/vow_flog/vow_flog_suite_test.go
+++ b/pkg/transformers/vow_flog/vow_flog_suite_test.go
@@ -1,16 +1,18 @@
-// Copyright 2018 Vulcanize
-//
-// 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.
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
package vow_flog
diff --git a/postgraphile/package.json b/postgraphile/package.json
index 8f2f1b15..9c3dc3fa 100644
--- a/postgraphile/package.json
+++ b/postgraphile/package.json
@@ -15,7 +15,7 @@
"url": "git+https://github.com/vulcanize/vulcanizedb.git"
},
"author": "Vulcanize, Inc.",
- "license": "Apache-2.0",
+ "license": "AGPL-3.0",
"bugs": {
"url": "https://github.com/vulcanize/vulcanizedb/issues"
},
diff --git a/test_config/test_config.go b/test_config/test_config.go
index cc9db3c1..726c438a 100644
--- a/test_config/test_config.go
+++ b/test_config/test_config.go
@@ -1,11 +1,27 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package test_config
import (
"fmt"
- log "github.com/sirupsen/logrus"
"os"
. "github.com/onsi/gomega"
+ log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
"github.com/vulcanize/vulcanizedb/pkg/config"
diff --git a/utils/utils.go b/utils/utils.go
index 30d034f9..596d8ad3 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -1,13 +1,27 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
package utils
import (
- log "github.com/sirupsen/logrus"
-
+ "math/big"
+ "os"
"path/filepath"
- "math/big"
-
- "os"
+ log "github.com/sirupsen/logrus"
"github.com/vulcanize/vulcanizedb/pkg/config"
"github.com/vulcanize/vulcanizedb/pkg/core"
diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi.go
index 08d5db97..3b65dfa6 100644
--- a/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi.go
+++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi.go
@@ -89,6 +89,24 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) (err error) {
return fmt.Errorf("abi: could not locate named method or event")
}
+// Unpack output into a map according to the abi specification
+func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, output []byte) (err error) {
+ if len(output) == 0 {
+ return fmt.Errorf("abi: unmarshalling empty output")
+ }
+ // since there can't be naming collisions with contracts and events,
+ // we need to decide whether we're calling a method or an event
+ if method, ok := abi.Methods[name]; ok {
+ if len(output)%32 != 0 {
+ return fmt.Errorf("abi: improperly formatted output")
+ }
+ return method.Outputs.UnpackIntoMap(v, output)
+ } else if event, ok := abi.Events[name]; ok {
+ return event.Inputs.UnpackIntoMap(v, output)
+ }
+ return fmt.Errorf("abi: could not locate named method or event")
+}
+
// UnmarshalJSON implements json.Unmarshaler interface
func (abi *ABI) UnmarshalJSON(data []byte) error {
var fields []struct {
diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi_test.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi_test.go
index b9444f9f..6c2b7c2f 100644
--- a/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi_test.go
+++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/abi_test.go
@@ -694,6 +694,62 @@ func TestUnpackEvent(t *testing.T) {
}
}
+func TestUnpackIntoMapEvent(t *testing.T) {
+ const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]`
+ abi, err := JSON(strings.NewReader(abiJSON))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ const hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158`
+ data, err := hex.DecodeString(hexdata)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(data)%32 == 0 {
+ t.Errorf("len(data) is %d, want a non-multiple of 32", len(data))
+ }
+
+ receivedMap := map[string]interface{}{}
+ expectedReceivedMap := map[string]interface{}{
+ "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
+ "amount": big.NewInt(1),
+ "memo": []uint8{88},
+ }
+
+ err = abi.UnpackIntoMap(receivedMap, "received", data)
+ if err != nil {
+ t.Error(err)
+ }
+
+ if receivedMap["sender"] != expectedReceivedMap["sender"] {
+ t.Errorf("unpacked map does not match expected map")
+ }
+
+ if receivedMap["amount"].(*big.Int).String() != expectedReceivedMap["amount"].(*big.Int).String() {
+ t.Errorf("unpacked map does not match expected map")
+ }
+
+ u8 := receivedMap["memo"].([]uint8)
+ expectedU8 := expectedReceivedMap["memo"].([]uint8)
+ for i, v := range expectedU8 {
+ if u8[i] != v {
+ t.Errorf("unpacked map does not match expected map")
+ }
+ }
+
+ receivedAddrMap := map[string]interface{}{}
+
+ err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data)
+ if err != nil {
+ t.Error(err)
+ }
+
+ if receivedAddrMap["sender"] != expectedReceivedMap["sender"] {
+ t.Errorf("unpacked map does not match expected map")
+ }
+}
+
func TestABI_MethodById(t *testing.T) {
const abiJSON = `[
{"type":"function","name":"receive","constant":false,"inputs":[{"name":"memo","type":"bytes"}],"outputs":[],"payable":true,"stateMutability":"payable"},
diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/argument.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/argument.go
index d0a6b035..49cbf139 100644
--- a/vendor/github.com/ethereum/go-ethereum/accounts/abi/argument.go
+++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/argument.go
@@ -102,6 +102,16 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error {
return arguments.unpackAtomic(v, marshalledValues[0])
}
+// Unpack performs the operation hexdata -> mapping of argument name to argument value
+func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error {
+ marshalledValues, err := arguments.UnpackValues(data)
+ if err != nil {
+ return err
+ }
+
+ return arguments.unpackIntoMap(v, marshalledValues)
+}
+
// unpack sets the unmarshalled value to go format.
// Note the dst here must be settable.
func unpack(t *Type, dst interface{}, src interface{}) error {
@@ -160,6 +170,19 @@ func unpack(t *Type, dst interface{}, src interface{}) error {
return nil
}
+// Unpack arguments into map
+func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error {
+ // Make sure map is not nil
+ if v == nil {
+ return fmt.Errorf("abi: cannot unpack into a nil map")
+ }
+
+ for i, arg := range arguments.NonIndexed() {
+ v[arg.Name] = marshalledValues[i]
+ }
+ return nil
+}
+
// unpackAtomic unpacks ( hexdata -> go ) a single value
func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error {
if arguments.LengthNonIndexed() == 0 {
diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/base.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/base.go
index c37bdf11..f70f911d 100644
--- a/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/base.go
+++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/base.go
@@ -340,6 +340,22 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log)
return parseTopics(out, indexed, log.Topics[1:])
}
+// UnpackLogIntoMap unpacks a retrieved log into the provided map.
+func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error {
+ if len(log.Data) > 0 {
+ if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil {
+ return err
+ }
+ }
+ var indexed abi.Arguments
+ for _, arg := range c.abi.Events[event].Inputs {
+ if arg.Indexed {
+ indexed = append(indexed, arg)
+ }
+ }
+ return parseTopicsIntoMap(out, indexed, log.Topics[1:])
+}
+
// ensureContext is a helper method to ensure a context is not nil, even if the
// user specified it as such.
func ensureContext(ctx context.Context) context.Context {
diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/topics.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/topics.go
index 600dfcda..cd84fb16 100644
--- a/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/topics.go
+++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/topics.go
@@ -187,3 +187,42 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er
}
return nil
}
+
+// parseTopics converts the indexed topic field-value pairs into map key-value pairs
+func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error {
+ // Sanity check that the fields and topics match up
+ if len(fields) != len(topics) {
+ return errors.New("topic/field count mismatch")
+ }
+ // Iterate over all the fields and reconstruct them from topics
+ for _, arg := range fields {
+ if !arg.Indexed {
+ return errors.New("non-indexed field in topic reconstruction")
+ }
+
+ switch arg.Type.T {
+ case abi.BoolTy:
+ if topics[0][common.HashLength-1] == 1 {
+ out[arg.Name] = true
+ } else {
+ out[arg.Name] = false
+ }
+ case abi.IntTy, abi.UintTy:
+ num := new(big.Int).SetBytes(topics[0][:])
+ out[arg.Name] = num
+ case abi.AddressTy:
+ var addr common.Address
+ copy(addr[:], topics[0][common.HashLength-common.AddressLength:])
+ out[arg.Name] = addr
+ case abi.HashTy:
+ out[arg.Name] = topics[0]
+ case abi.BytesTy, abi.FixedBytesTy:
+ out[arg.Name] = topics[0][:]
+ default:
+ }
+
+ topics = topics[1:]
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/accounts/abi/reflect.go b/vendor/github.com/ethereum/go-ethereum/accounts/abi/reflect.go
index 1b0bb004..ccc6a659 100644
--- a/vendor/github.com/ethereum/go-ethereum/accounts/abi/reflect.go
+++ b/vendor/github.com/ethereum/go-ethereum/accounts/abi/reflect.go
@@ -74,7 +74,7 @@ func mustArrayToByteSlice(value reflect.Value) reflect.Value {
func set(dst, src reflect.Value) error {
dstType, srcType := dst.Type(), src.Type()
switch {
- case dstType.Kind() == reflect.Interface:
+ case dstType.Kind() == reflect.Interface && dst.Elem().IsValid():
return set(dst.Elem(), src)
case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT:
return set(dst.Elem(), src)
diff --git a/vendor/github.com/hashicorp/golang-lru/.gitignore b/vendor/github.com/hashicorp/golang-lru/.gitignore
new file mode 100644
index 00000000..83656241
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/.gitignore
@@ -0,0 +1,23 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
diff --git a/vendor/github.com/hashicorp/golang-lru/2q.go b/vendor/github.com/hashicorp/golang-lru/2q.go
new file mode 100644
index 00000000..e474cd07
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/2q.go
@@ -0,0 +1,223 @@
+package lru
+
+import (
+ "fmt"
+ "sync"
+
+ "github.com/hashicorp/golang-lru/simplelru"
+)
+
+const (
+ // Default2QRecentRatio is the ratio of the 2Q cache dedicated
+ // to recently added entries that have only been accessed once.
+ Default2QRecentRatio = 0.25
+
+ // Default2QGhostEntries is the default ratio of ghost
+ // entries kept to track entries recently evicted
+ Default2QGhostEntries = 0.50
+)
+
+// TwoQueueCache is a thread-safe fixed size 2Q cache.
+// 2Q is an enhancement over the standard LRU cache
+// in that it tracks both frequently and recently used
+// entries separately. This avoids a burst in access to new
+// entries from evicting frequently used entries. It adds some
+// additional tracking overhead to the standard LRU cache, and is
+// computationally about 2x the cost, and adds some metadata over
+// head. The ARCCache is similar, but does not require setting any
+// parameters.
+type TwoQueueCache struct {
+ size int
+ recentSize int
+
+ recent simplelru.LRUCache
+ frequent simplelru.LRUCache
+ recentEvict simplelru.LRUCache
+ lock sync.RWMutex
+}
+
+// New2Q creates a new TwoQueueCache using the default
+// values for the parameters.
+func New2Q(size int) (*TwoQueueCache, error) {
+ return New2QParams(size, Default2QRecentRatio, Default2QGhostEntries)
+}
+
+// New2QParams creates a new TwoQueueCache using the provided
+// parameter values.
+func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCache, error) {
+ if size <= 0 {
+ return nil, fmt.Errorf("invalid size")
+ }
+ if recentRatio < 0.0 || recentRatio > 1.0 {
+ return nil, fmt.Errorf("invalid recent ratio")
+ }
+ if ghostRatio < 0.0 || ghostRatio > 1.0 {
+ return nil, fmt.Errorf("invalid ghost ratio")
+ }
+
+ // Determine the sub-sizes
+ recentSize := int(float64(size) * recentRatio)
+ evictSize := int(float64(size) * ghostRatio)
+
+ // Allocate the LRUs
+ recent, err := simplelru.NewLRU(size, nil)
+ if err != nil {
+ return nil, err
+ }
+ frequent, err := simplelru.NewLRU(size, nil)
+ if err != nil {
+ return nil, err
+ }
+ recentEvict, err := simplelru.NewLRU(evictSize, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ // Initialize the cache
+ c := &TwoQueueCache{
+ size: size,
+ recentSize: recentSize,
+ recent: recent,
+ frequent: frequent,
+ recentEvict: recentEvict,
+ }
+ return c, nil
+}
+
+// Get looks up a key's value from the cache.
+func (c *TwoQueueCache) Get(key interface{}) (value interface{}, ok bool) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ // Check if this is a frequent value
+ if val, ok := c.frequent.Get(key); ok {
+ return val, ok
+ }
+
+ // If the value is contained in recent, then we
+ // promote it to frequent
+ if val, ok := c.recent.Peek(key); ok {
+ c.recent.Remove(key)
+ c.frequent.Add(key, val)
+ return val, ok
+ }
+
+ // No hit
+ return nil, false
+}
+
+// Add adds a value to the cache.
+func (c *TwoQueueCache) Add(key, value interface{}) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ // Check if the value is frequently used already,
+ // and just update the value
+ if c.frequent.Contains(key) {
+ c.frequent.Add(key, value)
+ return
+ }
+
+ // Check if the value is recently used, and promote
+ // the value into the frequent list
+ if c.recent.Contains(key) {
+ c.recent.Remove(key)
+ c.frequent.Add(key, value)
+ return
+ }
+
+ // If the value was recently evicted, add it to the
+ // frequently used list
+ if c.recentEvict.Contains(key) {
+ c.ensureSpace(true)
+ c.recentEvict.Remove(key)
+ c.frequent.Add(key, value)
+ return
+ }
+
+ // Add to the recently seen list
+ c.ensureSpace(false)
+ c.recent.Add(key, value)
+ return
+}
+
+// ensureSpace is used to ensure we have space in the cache
+func (c *TwoQueueCache) ensureSpace(recentEvict bool) {
+ // If we have space, nothing to do
+ recentLen := c.recent.Len()
+ freqLen := c.frequent.Len()
+ if recentLen+freqLen < c.size {
+ return
+ }
+
+ // If the recent buffer is larger than
+ // the target, evict from there
+ if recentLen > 0 && (recentLen > c.recentSize || (recentLen == c.recentSize && !recentEvict)) {
+ k, _, _ := c.recent.RemoveOldest()
+ c.recentEvict.Add(k, nil)
+ return
+ }
+
+ // Remove from the frequent list otherwise
+ c.frequent.RemoveOldest()
+}
+
+// Len returns the number of items in the cache.
+func (c *TwoQueueCache) Len() int {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.recent.Len() + c.frequent.Len()
+}
+
+// Keys returns a slice of the keys in the cache.
+// The frequently used keys are first in the returned slice.
+func (c *TwoQueueCache) Keys() []interface{} {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ k1 := c.frequent.Keys()
+ k2 := c.recent.Keys()
+ return append(k1, k2...)
+}
+
+// Remove removes the provided key from the cache.
+func (c *TwoQueueCache) Remove(key interface{}) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if c.frequent.Remove(key) {
+ return
+ }
+ if c.recent.Remove(key) {
+ return
+ }
+ if c.recentEvict.Remove(key) {
+ return
+ }
+}
+
+// Purge is used to completely clear the cache.
+func (c *TwoQueueCache) Purge() {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ c.recent.Purge()
+ c.frequent.Purge()
+ c.recentEvict.Purge()
+}
+
+// Contains is used to check if the cache contains a key
+// without updating recency or frequency.
+func (c *TwoQueueCache) Contains(key interface{}) bool {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.frequent.Contains(key) || c.recent.Contains(key)
+}
+
+// Peek is used to inspect the cache value of a key
+// without updating recency or frequency.
+func (c *TwoQueueCache) Peek(key interface{}) (value interface{}, ok bool) {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ if val, ok := c.frequent.Peek(key); ok {
+ return val, ok
+ }
+ return c.recent.Peek(key)
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/2q_test.go b/vendor/github.com/hashicorp/golang-lru/2q_test.go
new file mode 100644
index 00000000..1b0f3518
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/2q_test.go
@@ -0,0 +1,306 @@
+package lru
+
+import (
+ "math/rand"
+ "testing"
+)
+
+func Benchmark2Q_Rand(b *testing.B) {
+ l, err := New2Q(8192)
+ if err != nil {
+ b.Fatalf("err: %v", err)
+ }
+
+ trace := make([]int64, b.N*2)
+ for i := 0; i < b.N*2; i++ {
+ trace[i] = rand.Int63() % 32768
+ }
+
+ b.ResetTimer()
+
+ var hit, miss int
+ for i := 0; i < 2*b.N; i++ {
+ if i%2 == 0 {
+ l.Add(trace[i], trace[i])
+ } else {
+ _, ok := l.Get(trace[i])
+ if ok {
+ hit++
+ } else {
+ miss++
+ }
+ }
+ }
+ b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
+}
+
+func Benchmark2Q_Freq(b *testing.B) {
+ l, err := New2Q(8192)
+ if err != nil {
+ b.Fatalf("err: %v", err)
+ }
+
+ trace := make([]int64, b.N*2)
+ for i := 0; i < b.N*2; i++ {
+ if i%2 == 0 {
+ trace[i] = rand.Int63() % 16384
+ } else {
+ trace[i] = rand.Int63() % 32768
+ }
+ }
+
+ b.ResetTimer()
+
+ for i := 0; i < b.N; i++ {
+ l.Add(trace[i], trace[i])
+ }
+ var hit, miss int
+ for i := 0; i < b.N; i++ {
+ _, ok := l.Get(trace[i])
+ if ok {
+ hit++
+ } else {
+ miss++
+ }
+ }
+ b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
+}
+
+func Test2Q_RandomOps(t *testing.T) {
+ size := 128
+ l, err := New2Q(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ n := 200000
+ for i := 0; i < n; i++ {
+ key := rand.Int63() % 512
+ r := rand.Int63()
+ switch r % 3 {
+ case 0:
+ l.Add(key, key)
+ case 1:
+ l.Get(key)
+ case 2:
+ l.Remove(key)
+ }
+
+ if l.recent.Len()+l.frequent.Len() > size {
+ t.Fatalf("bad: recent: %d freq: %d",
+ l.recent.Len(), l.frequent.Len())
+ }
+ }
+}
+
+func Test2Q_Get_RecentToFrequent(t *testing.T) {
+ l, err := New2Q(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ // Touch all the entries, should be in t1
+ for i := 0; i < 128; i++ {
+ l.Add(i, i)
+ }
+ if n := l.recent.Len(); n != 128 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Get should upgrade to t2
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("missing: %d", i)
+ }
+ }
+ if n := l.recent.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 128 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Get be from t2
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("missing: %d", i)
+ }
+ }
+ if n := l.recent.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 128 {
+ t.Fatalf("bad: %d", n)
+ }
+}
+
+func Test2Q_Add_RecentToFrequent(t *testing.T) {
+ l, err := New2Q(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ // Add initially to recent
+ l.Add(1, 1)
+ if n := l.recent.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Add should upgrade to frequent
+ l.Add(1, 1)
+ if n := l.recent.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Add should remain in frequent
+ l.Add(1, 1)
+ if n := l.recent.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+}
+
+func Test2Q_Add_RecentEvict(t *testing.T) {
+ l, err := New2Q(4)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ // Add 1,2,3,4,5 -> Evict 1
+ l.Add(1, 1)
+ l.Add(2, 2)
+ l.Add(3, 3)
+ l.Add(4, 4)
+ l.Add(5, 5)
+ if n := l.recent.Len(); n != 4 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.recentEvict.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Pull in the recently evicted
+ l.Add(1, 1)
+ if n := l.recent.Len(); n != 3 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.recentEvict.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Add 6, should cause another recent evict
+ l.Add(6, 6)
+ if n := l.recent.Len(); n != 3 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.recentEvict.Len(); n != 2 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.frequent.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+}
+
+func Test2Q(t *testing.T) {
+ l, err := New2Q(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ for i := 0; i < 256; i++ {
+ l.Add(i, i)
+ }
+ if l.Len() != 128 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+
+ for i, k := range l.Keys() {
+ if v, ok := l.Get(k); !ok || v != k || v != i+128 {
+ t.Fatalf("bad key: %v", k)
+ }
+ }
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if ok {
+ t.Fatalf("should be evicted")
+ }
+ }
+ for i := 128; i < 256; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("should not be evicted")
+ }
+ }
+ for i := 128; i < 192; i++ {
+ l.Remove(i)
+ _, ok := l.Get(i)
+ if ok {
+ t.Fatalf("should be deleted")
+ }
+ }
+
+ l.Purge()
+ if l.Len() != 0 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+ if _, ok := l.Get(200); ok {
+ t.Fatalf("should contain nothing")
+ }
+}
+
+// Test that Contains doesn't update recent-ness
+func Test2Q_Contains(t *testing.T) {
+ l, err := New2Q(2)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if !l.Contains(1) {
+ t.Errorf("1 should be contained")
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("Contains should not have updated recent-ness of 1")
+ }
+}
+
+// Test that Peek doesn't update recent-ness
+func Test2Q_Peek(t *testing.T) {
+ l, err := New2Q(2)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if v, ok := l.Peek(1); !ok || v != 1 {
+ t.Errorf("1 should be set to 1: %v, %v", v, ok)
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("should not have updated recent-ness of 1")
+ }
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/LICENSE b/vendor/github.com/hashicorp/golang-lru/LICENSE
new file mode 100644
index 00000000..be2cc4df
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/LICENSE
@@ -0,0 +1,362 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. "Contributor"
+
+ means each individual or legal entity that creates, contributes to the
+ creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+
+ means the combination of the Contributions of others (if any) used by a
+ Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+
+ means Source Code Form to which the initial Contributor has attached the
+ notice in Exhibit A, the Executable Form of such Source Code Form, and
+ Modifications of such Source Code Form, in each case including portions
+ thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ a. that the initial Contributor has attached the notice described in
+ Exhibit B to the Covered Software; or
+
+ b. that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the terms of
+ a Secondary License.
+
+1.6. "Executable Form"
+
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+
+ means a work that combines Covered Software with other material, in a
+ separate file or files, that is not Covered Software.
+
+1.8. "License"
+
+ means this document.
+
+1.9. "Licensable"
+
+ means having the right to grant, to the maximum extent possible, whether
+ at the time of the initial grant or subsequently, any and all of the
+ rights conveyed by this License.
+
+1.10. "Modifications"
+
+ means any of the following:
+
+ a. any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered Software; or
+
+ b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. "Patent Claims" of a Contributor
+
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the License,
+ by the making, using, selling, offering for sale, having made, import,
+ or transfer of either its Contributions or its Contributor Version.
+
+1.12. "Secondary License"
+
+ means either the GNU General Public License, Version 2.0, the GNU Lesser
+ General Public License, Version 2.1, the GNU Affero General Public
+ License, Version 3.0, or any later versions of those licenses.
+
+1.13. "Source Code Form"
+
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that controls, is
+ controlled by, or is under common control with You. For purposes of this
+ definition, "control" means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by contract or
+ otherwise, or (b) ownership of more than fifty percent (50%) of the
+ outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ a. under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+ b. under Patent Claims of such Contributor to make, use, sell, offer for
+ sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+ The licenses granted in Section 2.1 with respect to any Contribution
+ become effective for each Contribution on the date the Contributor first
+ distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+ The licenses granted in this Section 2 are the only rights granted under
+ this License. No additional rights or licenses will be implied from the
+ distribution or licensing of Covered Software under this License.
+ Notwithstanding Section 2.1(b) above, no patent license is granted by a
+ Contributor:
+
+ a. for any code that a Contributor has removed from Covered Software; or
+
+ b. for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+ c. under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+ This License does not grant any rights in the trademarks, service marks,
+ or logos of any Contributor (except as may be necessary to comply with
+ the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+ No Contributor makes additional grants as a result of Your choice to
+ distribute the Covered Software under a subsequent version of this
+ License (see Section 10.2) or under the terms of a Secondary License (if
+ permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+ Each Contributor represents that the Contributor believes its
+ Contributions are its original creation(s) or it has sufficient rights to
+ grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+ This License is not intended to limit any rights You have under
+ applicable copyright doctrines of fair use, fair dealing, or other
+ equivalents.
+
+2.7. Conditions
+
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+ Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+ All distribution of Covered Software in Source Code Form, including any
+ Modifications that You create or to which You contribute, must be under
+ the terms of this License. You must inform recipients that the Source
+ Code Form of the Covered Software is governed by the terms of this
+ License, and how they can obtain a copy of this License. You may not
+ attempt to alter or restrict the recipients' rights in the Source Code
+ Form.
+
+3.2. Distribution of Executable Form
+
+ If You distribute Covered Software in Executable Form then:
+
+ a. such Covered Software must also be made available in Source Code Form,
+ as described in Section 3.1, and You must inform recipients of the
+ Executable Form how they can obtain a copy of such Source Code Form by
+ reasonable means in a timely manner, at a charge no more than the cost
+ of distribution to the recipient; and
+
+ b. You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter the
+ recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+ You may create and distribute a Larger Work under terms of Your choice,
+ provided that You also comply with the requirements of this License for
+ the Covered Software. If the Larger Work is a combination of Covered
+ Software with a work governed by one or more Secondary Licenses, and the
+ Covered Software is not Incompatible With Secondary Licenses, this
+ License permits You to additionally distribute such Covered Software
+ under the terms of such Secondary License(s), so that the recipient of
+ the Larger Work may, at their option, further distribute the Covered
+ Software under the terms of either this License or such Secondary
+ License(s).
+
+3.4. Notices
+
+ You may not remove or alter the substance of any license notices
+ (including copyright notices, patent notices, disclaimers of warranty, or
+ limitations of liability) contained within the Source Code Form of the
+ Covered Software, except that You may alter any license notices to the
+ extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+ You may choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of Covered
+ Software. However, You may do so only on Your own behalf, and not on
+ behalf of any Contributor. You must make it absolutely clear that any
+ such warranty, support, indemnity, or liability obligation is offered by
+ You alone, and You hereby agree to indemnify every Contributor for any
+ liability incurred by such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer. You may include additional
+ disclaimers of warranty and limitations of liability specific to any
+ jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+ If it is impossible for You to comply with any of the terms of this License
+ with respect to some or all of the Covered Software due to statute,
+ judicial order, or regulation then You must: (a) comply with the terms of
+ this License to the maximum extent possible; and (b) describe the
+ limitations and the code they affect. Such description must be placed in a
+ text file included with all distributions of the Covered Software under
+ this License. Except to the extent prohibited by statute or regulation,
+ such description must be sufficiently detailed for a recipient of ordinary
+ skill to be able to understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+ fail to comply with any of its terms. However, if You become compliant,
+ then the rights granted under this License from a particular Contributor
+ are reinstated (a) provisionally, unless and until such Contributor
+ explicitly and finally terminates Your grants, and (b) on an ongoing
+ basis, if such Contributor fails to notify You of the non-compliance by
+ some reasonable means prior to 60 days after You have come back into
+ compliance. Moreover, Your grants from a particular Contributor are
+ reinstated on an ongoing basis if such Contributor notifies You of the
+ non-compliance by some reasonable means, this is the first time You have
+ received notice of non-compliance with this License from such
+ Contributor, and You become compliant prior to 30 days after Your receipt
+ of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+ infringement claim (excluding declaratory judgment actions,
+ counter-claims, and cross-claims) alleging that a Contributor Version
+ directly or indirectly infringes any patent, then the rights granted to
+ You by any and all Contributors for the Covered Software under Section
+ 2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+ license agreements (excluding distributors and resellers) which have been
+ validly granted by You or Your distributors under this License prior to
+ termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+ Covered Software is provided under this License on an "as is" basis,
+ without warranty of any kind, either expressed, implied, or statutory,
+ including, without limitation, warranties that the Covered Software is free
+ of defects, merchantable, fit for a particular purpose or non-infringing.
+ The entire risk as to the quality and performance of the Covered Software
+ is with You. Should any Covered Software prove defective in any respect,
+ You (not any Contributor) assume the cost of any necessary servicing,
+ repair, or correction. This disclaimer of warranty constitutes an essential
+ part of this License. No use of any Covered Software is authorized under
+ this License except under this disclaimer.
+
+7. Limitation of Liability
+
+ Under no circumstances and under no legal theory, whether tort (including
+ negligence), contract, or otherwise, shall any Contributor, or anyone who
+ distributes Covered Software as permitted above, be liable to You for any
+ direct, indirect, special, incidental, or consequential damages of any
+ character including, without limitation, damages for lost profits, loss of
+ goodwill, work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses, even if such party shall have been
+ informed of the possibility of such damages. This limitation of liability
+ shall not apply to liability for death or personal injury resulting from
+ such party's negligence to the extent applicable law prohibits such
+ limitation. Some jurisdictions do not allow the exclusion or limitation of
+ incidental or consequential damages, so this exclusion and limitation may
+ not apply to You.
+
+8. Litigation
+
+ Any litigation relating to this License may be brought only in the courts
+ of a jurisdiction where the defendant maintains its principal place of
+ business and such litigation shall be governed by laws of that
+ jurisdiction, without reference to its conflict-of-law provisions. Nothing
+ in this Section shall prevent a party's ability to bring cross-claims or
+ counter-claims.
+
+9. Miscellaneous
+
+ This License represents the complete agreement concerning the subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. Any law or regulation which provides that
+ the language of a contract shall be construed against the drafter shall not
+ be used to construe this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+ Mozilla Foundation is the license steward. Except as provided in Section
+ 10.3, no one other than the license steward has the right to modify or
+ publish new versions of this License. Each version will be given a
+ distinguishing version number.
+
+10.2. Effect of New Versions
+
+ You may distribute the Covered Software under the terms of the version
+ of the License under which You originally received the Covered Software,
+ or under the terms of any subsequent version published by the license
+ steward.
+
+10.3. Modified Versions
+
+ If you create software not governed by this License, and you want to
+ create a new license for such software, you may create and use a
+ modified version of this License if you rename the license and remove
+ any references to the name of the license steward (except to note that
+ such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+ Licenses If You choose to distribute Source Code Form that is
+ Incompatible With Secondary Licenses under the terms of this version of
+ the License, the notice described in Exhibit B of this License must be
+ attached.
+
+Exhibit A - Source Code Form License Notice
+
+ This Source Code Form is subject to the
+ terms of the Mozilla Public License, v.
+ 2.0. If a copy of the MPL was not
+ distributed with this file, You can
+ obtain one at
+ http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file,
+then You may include the notice in a location (such as a LICENSE file in a
+relevant directory) where a recipient would be likely to look for such a
+notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+
+ This Source Code Form is "Incompatible
+ With Secondary Licenses", as defined by
+ the Mozilla Public License, v. 2.0.
diff --git a/vendor/github.com/hashicorp/golang-lru/README.md b/vendor/github.com/hashicorp/golang-lru/README.md
new file mode 100644
index 00000000..33e58cfa
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/README.md
@@ -0,0 +1,25 @@
+golang-lru
+==========
+
+This provides the `lru` package which implements a fixed-size
+thread safe LRU cache. It is based on the cache in Groupcache.
+
+Documentation
+=============
+
+Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru)
+
+Example
+=======
+
+Using the LRU is very simple:
+
+```go
+l, _ := New(128)
+for i := 0; i < 256; i++ {
+ l.Add(i, nil)
+}
+if l.Len() != 128 {
+ panic(fmt.Sprintf("bad len: %v", l.Len()))
+}
+```
diff --git a/vendor/github.com/hashicorp/golang-lru/arc.go b/vendor/github.com/hashicorp/golang-lru/arc.go
new file mode 100644
index 00000000..555225a2
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/arc.go
@@ -0,0 +1,257 @@
+package lru
+
+import (
+ "sync"
+
+ "github.com/hashicorp/golang-lru/simplelru"
+)
+
+// ARCCache is a thread-safe fixed size Adaptive Replacement Cache (ARC).
+// ARC is an enhancement over the standard LRU cache in that tracks both
+// frequency and recency of use. This avoids a burst in access to new
+// entries from evicting the frequently used older entries. It adds some
+// additional tracking overhead to a standard LRU cache, computationally
+// it is roughly 2x the cost, and the extra memory overhead is linear
+// with the size of the cache. ARC has been patented by IBM, but is
+// similar to the TwoQueueCache (2Q) which requires setting parameters.
+type ARCCache struct {
+ size int // Size is the total capacity of the cache
+ p int // P is the dynamic preference towards T1 or T2
+
+ t1 simplelru.LRUCache // T1 is the LRU for recently accessed items
+ b1 simplelru.LRUCache // B1 is the LRU for evictions from t1
+
+ t2 simplelru.LRUCache // T2 is the LRU for frequently accessed items
+ b2 simplelru.LRUCache // B2 is the LRU for evictions from t2
+
+ lock sync.RWMutex
+}
+
+// NewARC creates an ARC of the given size
+func NewARC(size int) (*ARCCache, error) {
+ // Create the sub LRUs
+ b1, err := simplelru.NewLRU(size, nil)
+ if err != nil {
+ return nil, err
+ }
+ b2, err := simplelru.NewLRU(size, nil)
+ if err != nil {
+ return nil, err
+ }
+ t1, err := simplelru.NewLRU(size, nil)
+ if err != nil {
+ return nil, err
+ }
+ t2, err := simplelru.NewLRU(size, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ // Initialize the ARC
+ c := &ARCCache{
+ size: size,
+ p: 0,
+ t1: t1,
+ b1: b1,
+ t2: t2,
+ b2: b2,
+ }
+ return c, nil
+}
+
+// Get looks up a key's value from the cache.
+func (c *ARCCache) Get(key interface{}) (value interface{}, ok bool) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ // If the value is contained in T1 (recent), then
+ // promote it to T2 (frequent)
+ if val, ok := c.t1.Peek(key); ok {
+ c.t1.Remove(key)
+ c.t2.Add(key, val)
+ return val, ok
+ }
+
+ // Check if the value is contained in T2 (frequent)
+ if val, ok := c.t2.Get(key); ok {
+ return val, ok
+ }
+
+ // No hit
+ return nil, false
+}
+
+// Add adds a value to the cache.
+func (c *ARCCache) Add(key, value interface{}) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ // Check if the value is contained in T1 (recent), and potentially
+ // promote it to frequent T2
+ if c.t1.Contains(key) {
+ c.t1.Remove(key)
+ c.t2.Add(key, value)
+ return
+ }
+
+ // Check if the value is already in T2 (frequent) and update it
+ if c.t2.Contains(key) {
+ c.t2.Add(key, value)
+ return
+ }
+
+ // Check if this value was recently evicted as part of the
+ // recently used list
+ if c.b1.Contains(key) {
+ // T1 set is too small, increase P appropriately
+ delta := 1
+ b1Len := c.b1.Len()
+ b2Len := c.b2.Len()
+ if b2Len > b1Len {
+ delta = b2Len / b1Len
+ }
+ if c.p+delta >= c.size {
+ c.p = c.size
+ } else {
+ c.p += delta
+ }
+
+ // Potentially need to make room in the cache
+ if c.t1.Len()+c.t2.Len() >= c.size {
+ c.replace(false)
+ }
+
+ // Remove from B1
+ c.b1.Remove(key)
+
+ // Add the key to the frequently used list
+ c.t2.Add(key, value)
+ return
+ }
+
+ // Check if this value was recently evicted as part of the
+ // frequently used list
+ if c.b2.Contains(key) {
+ // T2 set is too small, decrease P appropriately
+ delta := 1
+ b1Len := c.b1.Len()
+ b2Len := c.b2.Len()
+ if b1Len > b2Len {
+ delta = b1Len / b2Len
+ }
+ if delta >= c.p {
+ c.p = 0
+ } else {
+ c.p -= delta
+ }
+
+ // Potentially need to make room in the cache
+ if c.t1.Len()+c.t2.Len() >= c.size {
+ c.replace(true)
+ }
+
+ // Remove from B2
+ c.b2.Remove(key)
+
+ // Add the key to the frequently used list
+ c.t2.Add(key, value)
+ return
+ }
+
+ // Potentially need to make room in the cache
+ if c.t1.Len()+c.t2.Len() >= c.size {
+ c.replace(false)
+ }
+
+ // Keep the size of the ghost buffers trim
+ if c.b1.Len() > c.size-c.p {
+ c.b1.RemoveOldest()
+ }
+ if c.b2.Len() > c.p {
+ c.b2.RemoveOldest()
+ }
+
+ // Add to the recently seen list
+ c.t1.Add(key, value)
+ return
+}
+
+// replace is used to adaptively evict from either T1 or T2
+// based on the current learned value of P
+func (c *ARCCache) replace(b2ContainsKey bool) {
+ t1Len := c.t1.Len()
+ if t1Len > 0 && (t1Len > c.p || (t1Len == c.p && b2ContainsKey)) {
+ k, _, ok := c.t1.RemoveOldest()
+ if ok {
+ c.b1.Add(k, nil)
+ }
+ } else {
+ k, _, ok := c.t2.RemoveOldest()
+ if ok {
+ c.b2.Add(k, nil)
+ }
+ }
+}
+
+// Len returns the number of cached entries
+func (c *ARCCache) Len() int {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.t1.Len() + c.t2.Len()
+}
+
+// Keys returns all the cached keys
+func (c *ARCCache) Keys() []interface{} {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ k1 := c.t1.Keys()
+ k2 := c.t2.Keys()
+ return append(k1, k2...)
+}
+
+// Remove is used to purge a key from the cache
+func (c *ARCCache) Remove(key interface{}) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ if c.t1.Remove(key) {
+ return
+ }
+ if c.t2.Remove(key) {
+ return
+ }
+ if c.b1.Remove(key) {
+ return
+ }
+ if c.b2.Remove(key) {
+ return
+ }
+}
+
+// Purge is used to clear the cache
+func (c *ARCCache) Purge() {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ c.t1.Purge()
+ c.t2.Purge()
+ c.b1.Purge()
+ c.b2.Purge()
+}
+
+// Contains is used to check if the cache contains a key
+// without updating recency or frequency.
+func (c *ARCCache) Contains(key interface{}) bool {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.t1.Contains(key) || c.t2.Contains(key)
+}
+
+// Peek is used to inspect the cache value of a key
+// without updating recency or frequency.
+func (c *ARCCache) Peek(key interface{}) (value interface{}, ok bool) {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ if val, ok := c.t1.Peek(key); ok {
+ return val, ok
+ }
+ return c.t2.Peek(key)
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/arc_test.go b/vendor/github.com/hashicorp/golang-lru/arc_test.go
new file mode 100644
index 00000000..e2d9b68c
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/arc_test.go
@@ -0,0 +1,377 @@
+package lru
+
+import (
+ "math/rand"
+ "testing"
+ "time"
+)
+
+func init() {
+ rand.Seed(time.Now().Unix())
+}
+
+func BenchmarkARC_Rand(b *testing.B) {
+ l, err := NewARC(8192)
+ if err != nil {
+ b.Fatalf("err: %v", err)
+ }
+
+ trace := make([]int64, b.N*2)
+ for i := 0; i < b.N*2; i++ {
+ trace[i] = rand.Int63() % 32768
+ }
+
+ b.ResetTimer()
+
+ var hit, miss int
+ for i := 0; i < 2*b.N; i++ {
+ if i%2 == 0 {
+ l.Add(trace[i], trace[i])
+ } else {
+ _, ok := l.Get(trace[i])
+ if ok {
+ hit++
+ } else {
+ miss++
+ }
+ }
+ }
+ b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
+}
+
+func BenchmarkARC_Freq(b *testing.B) {
+ l, err := NewARC(8192)
+ if err != nil {
+ b.Fatalf("err: %v", err)
+ }
+
+ trace := make([]int64, b.N*2)
+ for i := 0; i < b.N*2; i++ {
+ if i%2 == 0 {
+ trace[i] = rand.Int63() % 16384
+ } else {
+ trace[i] = rand.Int63() % 32768
+ }
+ }
+
+ b.ResetTimer()
+
+ for i := 0; i < b.N; i++ {
+ l.Add(trace[i], trace[i])
+ }
+ var hit, miss int
+ for i := 0; i < b.N; i++ {
+ _, ok := l.Get(trace[i])
+ if ok {
+ hit++
+ } else {
+ miss++
+ }
+ }
+ b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
+}
+
+func TestARC_RandomOps(t *testing.T) {
+ size := 128
+ l, err := NewARC(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ n := 200000
+ for i := 0; i < n; i++ {
+ key := rand.Int63() % 512
+ r := rand.Int63()
+ switch r % 3 {
+ case 0:
+ l.Add(key, key)
+ case 1:
+ l.Get(key)
+ case 2:
+ l.Remove(key)
+ }
+
+ if l.t1.Len()+l.t2.Len() > size {
+ t.Fatalf("bad: t1: %d t2: %d b1: %d b2: %d p: %d",
+ l.t1.Len(), l.t2.Len(), l.b1.Len(), l.b2.Len(), l.p)
+ }
+ if l.b1.Len()+l.b2.Len() > size {
+ t.Fatalf("bad: t1: %d t2: %d b1: %d b2: %d p: %d",
+ l.t1.Len(), l.t2.Len(), l.b1.Len(), l.b2.Len(), l.p)
+ }
+ }
+}
+
+func TestARC_Get_RecentToFrequent(t *testing.T) {
+ l, err := NewARC(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ // Touch all the entries, should be in t1
+ for i := 0; i < 128; i++ {
+ l.Add(i, i)
+ }
+ if n := l.t1.Len(); n != 128 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Get should upgrade to t2
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("missing: %d", i)
+ }
+ }
+ if n := l.t1.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 128 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Get be from t2
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("missing: %d", i)
+ }
+ }
+ if n := l.t1.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 128 {
+ t.Fatalf("bad: %d", n)
+ }
+}
+
+func TestARC_Add_RecentToFrequent(t *testing.T) {
+ l, err := NewARC(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ // Add initially to t1
+ l.Add(1, 1)
+ if n := l.t1.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Add should upgrade to t2
+ l.Add(1, 1)
+ if n := l.t1.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Add should remain in t2
+ l.Add(1, 1)
+ if n := l.t1.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+}
+
+func TestARC_Adaptive(t *testing.T) {
+ l, err := NewARC(4)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ // Fill t1
+ for i := 0; i < 4; i++ {
+ l.Add(i, i)
+ }
+ if n := l.t1.Len(); n != 4 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Move to t2
+ l.Get(0)
+ l.Get(1)
+ if n := l.t2.Len(); n != 2 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Evict from t1
+ l.Add(4, 4)
+ if n := l.b1.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Current state
+ // t1 : (MRU) [4, 3] (LRU)
+ // t2 : (MRU) [1, 0] (LRU)
+ // b1 : (MRU) [2] (LRU)
+ // b2 : (MRU) [] (LRU)
+
+ // Add 2, should cause hit on b1
+ l.Add(2, 2)
+ if n := l.b1.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+ if l.p != 1 {
+ t.Fatalf("bad: %d", l.p)
+ }
+ if n := l.t2.Len(); n != 3 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Current state
+ // t1 : (MRU) [4] (LRU)
+ // t2 : (MRU) [2, 1, 0] (LRU)
+ // b1 : (MRU) [3] (LRU)
+ // b2 : (MRU) [] (LRU)
+
+ // Add 4, should migrate to t2
+ l.Add(4, 4)
+ if n := l.t1.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 4 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Current state
+ // t1 : (MRU) [] (LRU)
+ // t2 : (MRU) [4, 2, 1, 0] (LRU)
+ // b1 : (MRU) [3] (LRU)
+ // b2 : (MRU) [] (LRU)
+
+ // Add 4, should evict to b2
+ l.Add(5, 5)
+ if n := l.t1.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 3 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.b2.Len(); n != 1 {
+ t.Fatalf("bad: %d", n)
+ }
+
+ // Current state
+ // t1 : (MRU) [5] (LRU)
+ // t2 : (MRU) [4, 2, 1] (LRU)
+ // b1 : (MRU) [3] (LRU)
+ // b2 : (MRU) [0] (LRU)
+
+ // Add 0, should decrease p
+ l.Add(0, 0)
+ if n := l.t1.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.t2.Len(); n != 4 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.b1.Len(); n != 2 {
+ t.Fatalf("bad: %d", n)
+ }
+ if n := l.b2.Len(); n != 0 {
+ t.Fatalf("bad: %d", n)
+ }
+ if l.p != 0 {
+ t.Fatalf("bad: %d", l.p)
+ }
+
+ // Current state
+ // t1 : (MRU) [] (LRU)
+ // t2 : (MRU) [0, 4, 2, 1] (LRU)
+ // b1 : (MRU) [5, 3] (LRU)
+ // b2 : (MRU) [0] (LRU)
+}
+
+func TestARC(t *testing.T) {
+ l, err := NewARC(128)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ for i := 0; i < 256; i++ {
+ l.Add(i, i)
+ }
+ if l.Len() != 128 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+
+ for i, k := range l.Keys() {
+ if v, ok := l.Get(k); !ok || v != k || v != i+128 {
+ t.Fatalf("bad key: %v", k)
+ }
+ }
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if ok {
+ t.Fatalf("should be evicted")
+ }
+ }
+ for i := 128; i < 256; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("should not be evicted")
+ }
+ }
+ for i := 128; i < 192; i++ {
+ l.Remove(i)
+ _, ok := l.Get(i)
+ if ok {
+ t.Fatalf("should be deleted")
+ }
+ }
+
+ l.Purge()
+ if l.Len() != 0 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+ if _, ok := l.Get(200); ok {
+ t.Fatalf("should contain nothing")
+ }
+}
+
+// Test that Contains doesn't update recent-ness
+func TestARC_Contains(t *testing.T) {
+ l, err := NewARC(2)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if !l.Contains(1) {
+ t.Errorf("1 should be contained")
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("Contains should not have updated recent-ness of 1")
+ }
+}
+
+// Test that Peek doesn't update recent-ness
+func TestARC_Peek(t *testing.T) {
+ l, err := NewARC(2)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if v, ok := l.Peek(1); !ok || v != 1 {
+ t.Errorf("1 should be set to 1: %v, %v", v, ok)
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("should not have updated recent-ness of 1")
+ }
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/doc.go b/vendor/github.com/hashicorp/golang-lru/doc.go
new file mode 100644
index 00000000..2547df97
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/doc.go
@@ -0,0 +1,21 @@
+// Package lru provides three different LRU caches of varying sophistication.
+//
+// Cache is a simple LRU cache. It is based on the
+// LRU implementation in groupcache:
+// https://github.com/golang/groupcache/tree/master/lru
+//
+// TwoQueueCache tracks frequently used and recently used entries separately.
+// This avoids a burst of accesses from taking out frequently used entries,
+// at the cost of about 2x computational overhead and some extra bookkeeping.
+//
+// ARCCache is an adaptive replacement cache. It tracks recent evictions as
+// well as recent usage in both the frequent and recent caches. Its
+// computational overhead is comparable to TwoQueueCache, but the memory
+// overhead is linear with the size of the cache.
+//
+// ARC has been patented by IBM, so do not use it if that is problematic for
+// your program.
+//
+// All caches in this package take locks while operating, and are therefore
+// thread-safe for consumers.
+package lru
diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go
new file mode 100644
index 00000000..c8d9b0a2
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/lru.go
@@ -0,0 +1,110 @@
+package lru
+
+import (
+ "sync"
+
+ "github.com/hashicorp/golang-lru/simplelru"
+)
+
+// Cache is a thread-safe fixed size LRU cache.
+type Cache struct {
+ lru simplelru.LRUCache
+ lock sync.RWMutex
+}
+
+// New creates an LRU of the given size.
+func New(size int) (*Cache, error) {
+ return NewWithEvict(size, nil)
+}
+
+// NewWithEvict constructs a fixed size cache with the given eviction
+// callback.
+func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) {
+ lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted))
+ if err != nil {
+ return nil, err
+ }
+ c := &Cache{
+ lru: lru,
+ }
+ return c, nil
+}
+
+// Purge is used to completely clear the cache.
+func (c *Cache) Purge() {
+ c.lock.Lock()
+ c.lru.Purge()
+ c.lock.Unlock()
+}
+
+// Add adds a value to the cache. Returns true if an eviction occurred.
+func (c *Cache) Add(key, value interface{}) (evicted bool) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ return c.lru.Add(key, value)
+}
+
+// Get looks up a key's value from the cache.
+func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ return c.lru.Get(key)
+}
+
+// Contains checks if a key is in the cache, without updating the
+// recent-ness or deleting it for being stale.
+func (c *Cache) Contains(key interface{}) bool {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.lru.Contains(key)
+}
+
+// Peek returns the key value (or undefined if not found) without updating
+// the "recently used"-ness of the key.
+func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.lru.Peek(key)
+}
+
+// ContainsOrAdd checks if a key is in the cache without updating the
+// recent-ness or deleting it for being stale, and if not, adds the value.
+// Returns whether found and whether an eviction occurred.
+func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ if c.lru.Contains(key) {
+ return true, false
+ }
+ evicted = c.lru.Add(key, value)
+ return false, evicted
+}
+
+// Remove removes the provided key from the cache.
+func (c *Cache) Remove(key interface{}) {
+ c.lock.Lock()
+ c.lru.Remove(key)
+ c.lock.Unlock()
+}
+
+// RemoveOldest removes the oldest item from the cache.
+func (c *Cache) RemoveOldest() {
+ c.lock.Lock()
+ c.lru.RemoveOldest()
+ c.lock.Unlock()
+}
+
+// Keys returns a slice of the keys in the cache, from oldest to newest.
+func (c *Cache) Keys() []interface{} {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.lru.Keys()
+}
+
+// Len returns the number of items in the cache.
+func (c *Cache) Len() int {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.lru.Len()
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/lru_test.go b/vendor/github.com/hashicorp/golang-lru/lru_test.go
new file mode 100644
index 00000000..e7e23505
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/lru_test.go
@@ -0,0 +1,221 @@
+package lru
+
+import (
+ "math/rand"
+ "testing"
+)
+
+func BenchmarkLRU_Rand(b *testing.B) {
+ l, err := New(8192)
+ if err != nil {
+ b.Fatalf("err: %v", err)
+ }
+
+ trace := make([]int64, b.N*2)
+ for i := 0; i < b.N*2; i++ {
+ trace[i] = rand.Int63() % 32768
+ }
+
+ b.ResetTimer()
+
+ var hit, miss int
+ for i := 0; i < 2*b.N; i++ {
+ if i%2 == 0 {
+ l.Add(trace[i], trace[i])
+ } else {
+ _, ok := l.Get(trace[i])
+ if ok {
+ hit++
+ } else {
+ miss++
+ }
+ }
+ }
+ b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
+}
+
+func BenchmarkLRU_Freq(b *testing.B) {
+ l, err := New(8192)
+ if err != nil {
+ b.Fatalf("err: %v", err)
+ }
+
+ trace := make([]int64, b.N*2)
+ for i := 0; i < b.N*2; i++ {
+ if i%2 == 0 {
+ trace[i] = rand.Int63() % 16384
+ } else {
+ trace[i] = rand.Int63() % 32768
+ }
+ }
+
+ b.ResetTimer()
+
+ for i := 0; i < b.N; i++ {
+ l.Add(trace[i], trace[i])
+ }
+ var hit, miss int
+ for i := 0; i < b.N; i++ {
+ _, ok := l.Get(trace[i])
+ if ok {
+ hit++
+ } else {
+ miss++
+ }
+ }
+ b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
+}
+
+func TestLRU(t *testing.T) {
+ evictCounter := 0
+ onEvicted := func(k interface{}, v interface{}) {
+ if k != v {
+ t.Fatalf("Evict values not equal (%v!=%v)", k, v)
+ }
+ evictCounter++
+ }
+ l, err := NewWithEvict(128, onEvicted)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ for i := 0; i < 256; i++ {
+ l.Add(i, i)
+ }
+ if l.Len() != 128 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+
+ if evictCounter != 128 {
+ t.Fatalf("bad evict count: %v", evictCounter)
+ }
+
+ for i, k := range l.Keys() {
+ if v, ok := l.Get(k); !ok || v != k || v != i+128 {
+ t.Fatalf("bad key: %v", k)
+ }
+ }
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if ok {
+ t.Fatalf("should be evicted")
+ }
+ }
+ for i := 128; i < 256; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("should not be evicted")
+ }
+ }
+ for i := 128; i < 192; i++ {
+ l.Remove(i)
+ _, ok := l.Get(i)
+ if ok {
+ t.Fatalf("should be deleted")
+ }
+ }
+
+ l.Get(192) // expect 192 to be last key in l.Keys()
+
+ for i, k := range l.Keys() {
+ if (i < 63 && k != i+193) || (i == 63 && k != 192) {
+ t.Fatalf("out of order key: %v", k)
+ }
+ }
+
+ l.Purge()
+ if l.Len() != 0 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+ if _, ok := l.Get(200); ok {
+ t.Fatalf("should contain nothing")
+ }
+}
+
+// test that Add returns true/false if an eviction occurred
+func TestLRUAdd(t *testing.T) {
+ evictCounter := 0
+ onEvicted := func(k interface{}, v interface{}) {
+ evictCounter++
+ }
+
+ l, err := NewWithEvict(1, onEvicted)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ if l.Add(1, 1) == true || evictCounter != 0 {
+ t.Errorf("should not have an eviction")
+ }
+ if l.Add(2, 2) == false || evictCounter != 1 {
+ t.Errorf("should have an eviction")
+ }
+}
+
+// test that Contains doesn't update recent-ness
+func TestLRUContains(t *testing.T) {
+ l, err := New(2)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if !l.Contains(1) {
+ t.Errorf("1 should be contained")
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("Contains should not have updated recent-ness of 1")
+ }
+}
+
+// test that Contains doesn't update recent-ness
+func TestLRUContainsOrAdd(t *testing.T) {
+ l, err := New(2)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ contains, evict := l.ContainsOrAdd(1, 1)
+ if !contains {
+ t.Errorf("1 should be contained")
+ }
+ if evict {
+ t.Errorf("nothing should be evicted here")
+ }
+
+ l.Add(3, 3)
+ contains, evict = l.ContainsOrAdd(1, 1)
+ if contains {
+ t.Errorf("1 should not have been contained")
+ }
+ if !evict {
+ t.Errorf("an eviction should have occurred")
+ }
+ if !l.Contains(1) {
+ t.Errorf("now 1 should be contained")
+ }
+}
+
+// test that Peek doesn't update recent-ness
+func TestLRUPeek(t *testing.T) {
+ l, err := New(2)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if v, ok := l.Peek(1); !ok || v != 1 {
+ t.Errorf("1 should be set to 1: %v, %v", v, ok)
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("should not have updated recent-ness of 1")
+ }
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
new file mode 100644
index 00000000..5673773b
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
@@ -0,0 +1,161 @@
+package simplelru
+
+import (
+ "container/list"
+ "errors"
+)
+
+// EvictCallback is used to get a callback when a cache entry is evicted
+type EvictCallback func(key interface{}, value interface{})
+
+// LRU implements a non-thread safe fixed size LRU cache
+type LRU struct {
+ size int
+ evictList *list.List
+ items map[interface{}]*list.Element
+ onEvict EvictCallback
+}
+
+// entry is used to hold a value in the evictList
+type entry struct {
+ key interface{}
+ value interface{}
+}
+
+// NewLRU constructs an LRU of the given size
+func NewLRU(size int, onEvict EvictCallback) (*LRU, error) {
+ if size <= 0 {
+ return nil, errors.New("Must provide a positive size")
+ }
+ c := &LRU{
+ size: size,
+ evictList: list.New(),
+ items: make(map[interface{}]*list.Element),
+ onEvict: onEvict,
+ }
+ return c, nil
+}
+
+// Purge is used to completely clear the cache.
+func (c *LRU) Purge() {
+ for k, v := range c.items {
+ if c.onEvict != nil {
+ c.onEvict(k, v.Value.(*entry).value)
+ }
+ delete(c.items, k)
+ }
+ c.evictList.Init()
+}
+
+// Add adds a value to the cache. Returns true if an eviction occurred.
+func (c *LRU) Add(key, value interface{}) (evicted bool) {
+ // Check for existing item
+ if ent, ok := c.items[key]; ok {
+ c.evictList.MoveToFront(ent)
+ ent.Value.(*entry).value = value
+ return false
+ }
+
+ // Add new item
+ ent := &entry{key, value}
+ entry := c.evictList.PushFront(ent)
+ c.items[key] = entry
+
+ evict := c.evictList.Len() > c.size
+ // Verify size not exceeded
+ if evict {
+ c.removeOldest()
+ }
+ return evict
+}
+
+// Get looks up a key's value from the cache.
+func (c *LRU) Get(key interface{}) (value interface{}, ok bool) {
+ if ent, ok := c.items[key]; ok {
+ c.evictList.MoveToFront(ent)
+ return ent.Value.(*entry).value, true
+ }
+ return
+}
+
+// Contains checks if a key is in the cache, without updating the recent-ness
+// or deleting it for being stale.
+func (c *LRU) Contains(key interface{}) (ok bool) {
+ _, ok = c.items[key]
+ return ok
+}
+
+// Peek returns the key value (or undefined if not found) without updating
+// the "recently used"-ness of the key.
+func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) {
+ var ent *list.Element
+ if ent, ok = c.items[key]; ok {
+ return ent.Value.(*entry).value, true
+ }
+ return nil, ok
+}
+
+// Remove removes the provided key from the cache, returning if the
+// key was contained.
+func (c *LRU) Remove(key interface{}) (present bool) {
+ if ent, ok := c.items[key]; ok {
+ c.removeElement(ent)
+ return true
+ }
+ return false
+}
+
+// RemoveOldest removes the oldest item from the cache.
+func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) {
+ ent := c.evictList.Back()
+ if ent != nil {
+ c.removeElement(ent)
+ kv := ent.Value.(*entry)
+ return kv.key, kv.value, true
+ }
+ return nil, nil, false
+}
+
+// GetOldest returns the oldest entry
+func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) {
+ ent := c.evictList.Back()
+ if ent != nil {
+ kv := ent.Value.(*entry)
+ return kv.key, kv.value, true
+ }
+ return nil, nil, false
+}
+
+// Keys returns a slice of the keys in the cache, from oldest to newest.
+func (c *LRU) Keys() []interface{} {
+ keys := make([]interface{}, len(c.items))
+ i := 0
+ for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() {
+ keys[i] = ent.Value.(*entry).key
+ i++
+ }
+ return keys
+}
+
+// Len returns the number of items in the cache.
+func (c *LRU) Len() int {
+ return c.evictList.Len()
+}
+
+// removeOldest removes the oldest item from the cache.
+func (c *LRU) removeOldest() {
+ ent := c.evictList.Back()
+ if ent != nil {
+ c.removeElement(ent)
+ }
+}
+
+// removeElement is used to remove a given list element from the cache
+func (c *LRU) removeElement(e *list.Element) {
+ c.evictList.Remove(e)
+ kv := e.Value.(*entry)
+ delete(c.items, kv.key)
+ if c.onEvict != nil {
+ c.onEvict(kv.key, kv.value)
+ }
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
new file mode 100644
index 00000000..744cac01
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
@@ -0,0 +1,37 @@
+package simplelru
+
+
+// LRUCache is the interface for simple LRU cache.
+type LRUCache interface {
+ // Adds a value to the cache, returns true if an eviction occurred and
+ // updates the "recently used"-ness of the key.
+ Add(key, value interface{}) bool
+
+ // Returns key's value from the cache and
+ // updates the "recently used"-ness of the key. #value, isFound
+ Get(key interface{}) (value interface{}, ok bool)
+
+ // Check if a key exsists in cache without updating the recent-ness.
+ Contains(key interface{}) (ok bool)
+
+ // Returns key's value without updating the "recently used"-ness of the key.
+ Peek(key interface{}) (value interface{}, ok bool)
+
+ // Removes a key from the cache.
+ Remove(key interface{}) bool
+
+ // Removes the oldest entry from cache.
+ RemoveOldest() (interface{}, interface{}, bool)
+
+ // Returns the oldest entry from the cache. #key, value, isFound
+ GetOldest() (interface{}, interface{}, bool)
+
+ // Returns a slice of the keys in the cache, from oldest to newest.
+ Keys() []interface{}
+
+ // Returns the number of items in the cache.
+ Len() int
+
+ // Clear all cache entries
+ Purge()
+}
diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go
new file mode 100644
index 00000000..ca5676e1
--- /dev/null
+++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go
@@ -0,0 +1,167 @@
+package simplelru
+
+import "testing"
+
+func TestLRU(t *testing.T) {
+ evictCounter := 0
+ onEvicted := func(k interface{}, v interface{}) {
+ if k != v {
+ t.Fatalf("Evict values not equal (%v!=%v)", k, v)
+ }
+ evictCounter++
+ }
+ l, err := NewLRU(128, onEvicted)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ for i := 0; i < 256; i++ {
+ l.Add(i, i)
+ }
+ if l.Len() != 128 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+
+ if evictCounter != 128 {
+ t.Fatalf("bad evict count: %v", evictCounter)
+ }
+
+ for i, k := range l.Keys() {
+ if v, ok := l.Get(k); !ok || v != k || v != i+128 {
+ t.Fatalf("bad key: %v", k)
+ }
+ }
+ for i := 0; i < 128; i++ {
+ _, ok := l.Get(i)
+ if ok {
+ t.Fatalf("should be evicted")
+ }
+ }
+ for i := 128; i < 256; i++ {
+ _, ok := l.Get(i)
+ if !ok {
+ t.Fatalf("should not be evicted")
+ }
+ }
+ for i := 128; i < 192; i++ {
+ ok := l.Remove(i)
+ if !ok {
+ t.Fatalf("should be contained")
+ }
+ ok = l.Remove(i)
+ if ok {
+ t.Fatalf("should not be contained")
+ }
+ _, ok = l.Get(i)
+ if ok {
+ t.Fatalf("should be deleted")
+ }
+ }
+
+ l.Get(192) // expect 192 to be last key in l.Keys()
+
+ for i, k := range l.Keys() {
+ if (i < 63 && k != i+193) || (i == 63 && k != 192) {
+ t.Fatalf("out of order key: %v", k)
+ }
+ }
+
+ l.Purge()
+ if l.Len() != 0 {
+ t.Fatalf("bad len: %v", l.Len())
+ }
+ if _, ok := l.Get(200); ok {
+ t.Fatalf("should contain nothing")
+ }
+}
+
+func TestLRU_GetOldest_RemoveOldest(t *testing.T) {
+ l, err := NewLRU(128, nil)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+ for i := 0; i < 256; i++ {
+ l.Add(i, i)
+ }
+ k, _, ok := l.GetOldest()
+ if !ok {
+ t.Fatalf("missing")
+ }
+ if k.(int) != 128 {
+ t.Fatalf("bad: %v", k)
+ }
+
+ k, _, ok = l.RemoveOldest()
+ if !ok {
+ t.Fatalf("missing")
+ }
+ if k.(int) != 128 {
+ t.Fatalf("bad: %v", k)
+ }
+
+ k, _, ok = l.RemoveOldest()
+ if !ok {
+ t.Fatalf("missing")
+ }
+ if k.(int) != 129 {
+ t.Fatalf("bad: %v", k)
+ }
+}
+
+// Test that Add returns true/false if an eviction occurred
+func TestLRU_Add(t *testing.T) {
+ evictCounter := 0
+ onEvicted := func(k interface{}, v interface{}) {
+ evictCounter++
+ }
+
+ l, err := NewLRU(1, onEvicted)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ if l.Add(1, 1) == true || evictCounter != 0 {
+ t.Errorf("should not have an eviction")
+ }
+ if l.Add(2, 2) == false || evictCounter != 1 {
+ t.Errorf("should have an eviction")
+ }
+}
+
+// Test that Contains doesn't update recent-ness
+func TestLRU_Contains(t *testing.T) {
+ l, err := NewLRU(2, nil)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if !l.Contains(1) {
+ t.Errorf("1 should be contained")
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("Contains should not have updated recent-ness of 1")
+ }
+}
+
+// Test that Peek doesn't update recent-ness
+func TestLRU_Peek(t *testing.T) {
+ l, err := NewLRU(2, nil)
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ l.Add(1, 1)
+ l.Add(2, 2)
+ if v, ok := l.Peek(1); !ok || v != 1 {
+ t.Errorf("1 should be set to 1: %v, %v", v, ok)
+ }
+
+ l.Add(3, 3)
+ if l.Contains(1) {
+ t.Errorf("should not have updated recent-ness of 1")
+ }
+}