mirror of
https://gitee.com/BDWare/cp.git
synced 2025-01-09 17:34:08 +00:00
initial commit
This commit is contained in:
parent
93f028251c
commit
2ce7d65b74
20
.gitignore
vendored
20
.gitignore
vendored
@ -1,18 +1,2 @@
|
||||
# Build and Release Folders
|
||||
bin-debug/
|
||||
bin-release/
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
|
||||
# Other files and folders
|
||||
.settings/
|
||||
|
||||
# Executables
|
||||
*.swf
|
||||
*.air
|
||||
*.ipa
|
||||
*.apk
|
||||
|
||||
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
|
||||
# should NOT be excluded as they contain compiler settings and other important
|
||||
# information for Eclipse / Flash Builder.
|
||||
/recoverTestFiles/
|
||||
/build/
|
366
LICENSE
366
LICENSE
@ -1,127 +1,339 @@
|
||||
木兰宽松许可证, 第2版
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
木兰宽松许可证, 第2版
|
||||
2020年1月 http://license.coscl.org.cn/MulanPSL2
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
0. 定义
|
||||
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
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
“法人实体”是指提交贡献的机构及其“关联实体”。
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
“关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
1. 授予版权许可
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
2. 授予专利许可
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
3. 无商标许可
|
||||
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
4. 分发限制
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
5. 免责声明与责任限制
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
6. 语言
|
||||
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
条款结束
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
如何将木兰宽松许可证,第2版,应用到您的软件
|
||||
|
||||
如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
3, 请将如下声明文本放入每个源文件的头部注释中。
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
Copyright (c) [Year] [name of copyright holder]
|
||||
[Software Name] is licensed under Mulan PSL v2.
|
||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
You may obtain a copy of Mulan PSL v2 at:
|
||||
http://license.coscl.org.cn/MulanPSL2
|
||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
See the Mulan PSL v2 for more details.
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
Mulan Permissive Software License,Version 2
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
Mulan Permissive Software License,Version 2 (Mulan PSL v2)
|
||||
January 2020 http://license.coscl.org.cn/MulanPSL2
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
|
||||
|
||||
0. Definition
|
||||
|
||||
Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
|
||||
|
||||
Contribution means the copyrightable work licensed by a particular Contributor under this License.
|
||||
|
||||
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
|
||||
|
||||
Legal Entity means the entity making a Contribution and all its Affiliates.
|
||||
|
||||
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
1. Grant of Copyright License
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
2. Grant of Patent License
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
3. No Trademark License
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4.
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
4. Distribution Restriction
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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.
|
||||
|
||||
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
5. Disclaimer of Warranty and Limitation of Liability
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
NO WARRANTY
|
||||
|
||||
6. Language
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
|
||||
|
||||
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE 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.
|
||||
|
||||
END OF THE TERMS AND CONDITIONS
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
|
||||
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.
|
||||
|
||||
i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
|
||||
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
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
iii Attach the statement to the appropriate annotated syntax at the beginning of each source file.
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Copyright (c) [Year] [name of copyright holder]
|
||||
[Software Name] is licensed under Mulan PSL v2.
|
||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
You may obtain a copy of Mulan PSL v2 at:
|
||||
http://license.coscl.org.cn/MulanPSL2
|
||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
See the Mulan PSL v2 for more details.
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
74
build.gradle
Normal file
74
build.gradle
Normal file
@ -0,0 +1,74 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'application'
|
||||
}
|
||||
|
||||
mainClassName = 'org.bdware.sc.ContractProcess'
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDirs 'src/main/java', 'src/main/analysis', 'src/main/data-mask'
|
||||
}
|
||||
resources {
|
||||
srcDir 'src/main/resources'
|
||||
}
|
||||
}
|
||||
test {
|
||||
java {
|
||||
srcDirs 'src/test/java', 'src/test/data-mask'
|
||||
}
|
||||
resources {
|
||||
srcDir 'src/test/resources'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(":common")
|
||||
implementation project(":mockjava")
|
||||
|
||||
implementation 'com.atlassian.commonmark:commonmark:0.17.0'
|
||||
implementation 'com.idealista:format-preserving-encryption:1.0.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
|
||||
implementation 'com.sun.mail:javax.mail:1.6.2'
|
||||
implementation 'org.apache.commons:commons-math3:3.6.1'
|
||||
implementation 'org.codehaus.groovy:groovy-all:3.0.8'
|
||||
implementation 'org.jsoup:jsoup:1.14.2'
|
||||
|
||||
implementation fileTree(dir: 'lib', include: '*.jar')
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
}
|
||||
|
||||
jar {
|
||||
String libs = ''
|
||||
configurations.runtimeClasspath.each {
|
||||
libs = libs + " libs/" + it.name
|
||||
}
|
||||
|
||||
manifest {
|
||||
attributes 'Manifest-Version': project.version
|
||||
attributes 'Main-Class': mainClassName
|
||||
attributes 'Class-Path': libs
|
||||
}
|
||||
}
|
||||
|
||||
tasks.processResources.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
|
||||
|
||||
task copyLibs(type: Copy, dependsOn: ":common:jar") {
|
||||
into "./build/output/libs/"
|
||||
from configurations.runtimeClasspath
|
||||
}
|
||||
|
||||
task copyJar(type: Copy, dependsOn: ":cp:jar") {
|
||||
into "./build/output/"
|
||||
from "./build/libs/$project.name-${version}.jar"
|
||||
rename { String fileName -> "yjs.jar" }
|
||||
}
|
||||
|
||||
task buildBundle(dependsOn: [":cp:copyLibs", ":cp:copyJar"]) {
|
||||
doLast {
|
||||
println "buildBundle in ./build/output/ successfully"
|
||||
}
|
||||
}
|
BIN
lib/datax-common-0.0.1-SNAPSHOT.jar
Normal file
BIN
lib/datax-common-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
lib/datax-core-0.0.1-SNAPSHOT.jar
Normal file
BIN
lib/datax-core-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
lib/datax-transformer-0.0.1-SNAPSHOT.jar
Normal file
BIN
lib/datax-transformer-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
lib/nashorn.jar
Normal file
BIN
lib/nashorn.jar
Normal file
Binary file not shown.
BIN
lib/plugin-rdbms-util-0.0.1-SNAPSHOT.jar
Normal file
BIN
lib/plugin-rdbms-util-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
lib/streamwriter-0.0.1-SNAPSHOT.jar
Normal file
BIN
lib/streamwriter-0.0.1-SNAPSHOT.jar
Normal file
Binary file not shown.
337
src/main/data-mask/maskingJobs/MaskingJob.java
Normal file
337
src/main/data-mask/maskingJobs/MaskingJob.java
Normal file
@ -0,0 +1,337 @@
|
||||
package maskingJobs;
|
||||
|
||||
import com.alibaba.datax.common.element.*;
|
||||
import com.alibaba.datax.common.exception.DataXException;
|
||||
import com.alibaba.datax.common.util.Configuration;
|
||||
import com.alibaba.datax.core.transport.record.DefaultRecord;
|
||||
import com.alibaba.datax.core.transport.transformer.TransformerErrorCode;
|
||||
import com.alibaba.datax.core.transport.transformer.TransformerExecution;
|
||||
|
||||
import com.alibaba.datax.core.util.TransformerUtil;
|
||||
import com.alibaba.datax.core.util.container.ClassLoaderSwapper;
|
||||
import com.alibaba.datax.core.util.container.CoreConstant;
|
||||
import com.alibaba.datax.plugin.rdbms.reader.Key;
|
||||
import com.alibaba.datax.plugin.rdbms.reader.util.SingleTableSplitUtil;
|
||||
import com.alibaba.datax.plugin.rdbms.util.DBUtil;
|
||||
import com.alibaba.datax.plugin.rdbms.util.DBUtilErrorCode;
|
||||
import com.alibaba.datax.plugin.rdbms.util.DataBaseType;
|
||||
import com.alibaba.datax.plugin.rdbms.util.RdbmsException;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class MaskingJob {
|
||||
|
||||
DataBaseType dataBaseType = DataBaseType.MySql;
|
||||
private String username;
|
||||
private String password;
|
||||
private String jdbcUrl;
|
||||
private String table;
|
||||
private Configuration maskConf;
|
||||
private Configuration readerPara;
|
||||
private List<Record> buffer;
|
||||
private List<TransformerExecution> transformerExecs;
|
||||
|
||||
|
||||
public void init(String confContent) {
|
||||
maskConf = Configuration.from(confContent);
|
||||
System.out.println("maskConf"+maskConf.toString());
|
||||
System.out.println(("maskCOnfjob"+maskConf.get("job").toString()));
|
||||
readerPara = maskConf.getConfiguration(CoreConstant.DATAX_JOB_CONTENT_READER_PARAMETER);
|
||||
System.out.println(readerPara);
|
||||
username = readerPara.getString(Key.USERNAME);
|
||||
password = readerPara.getString(Key.PASSWORD);
|
||||
jdbcUrl = readerPara.getString(Key.JDBC_URL);
|
||||
table = readerPara.getString(Key.TABLE);
|
||||
buffer = new ArrayList<>();
|
||||
System.out.println("maskConf11"+maskConf.getConfiguration(CoreConstant.DATAX_JOB_CONTENT + "[0]"));
|
||||
transformerExecs = TransformerUtil.buildTransformerInfo(maskConf.getConfiguration(CoreConstant.DATAX_JOB_CONTENT + "[0]"));
|
||||
}
|
||||
|
||||
public String buildQuerySql() {
|
||||
String column = "*";
|
||||
//String column = readerPara.getString(Key.COLUMN);
|
||||
String table = readerPara.getString(Key.TABLE);
|
||||
String where = readerPara.getString(Key.WHERE, null);
|
||||
//String querySql = SingleTableSplitUtil.buildQuerySql(column, table, where) + " limit 100";
|
||||
String querySql = SingleTableSplitUtil.buildQuerySql(column, table, where) + " limit 100";
|
||||
|
||||
return querySql;
|
||||
}
|
||||
|
||||
public JsonPrimitive getMaskedData(String confContent) {
|
||||
init(confContent);
|
||||
return startRead();
|
||||
//return new JsonPrimitive(getResult());
|
||||
}
|
||||
|
||||
public JsonPrimitive startRead() {
|
||||
String querySql = buildQuerySql();
|
||||
System.out.println("startRead"+dataBaseType+jdbcUrl+username+password);
|
||||
Connection conn = DBUtil.getConnection(dataBaseType, jdbcUrl, username, password);
|
||||
System.out.println(dataBaseType+jdbcUrl+username+password);
|
||||
int columnNumber = 0;
|
||||
String res="";
|
||||
ArrayList<String>columnName=new ArrayList<>();
|
||||
try {
|
||||
ResultSet rs = DBUtil.query(conn, querySql);
|
||||
ResultSetMetaData metaData = rs.getMetaData();
|
||||
columnNumber = metaData.getColumnCount();
|
||||
for(int i=1;i<=metaData.getColumnCount();i++){
|
||||
//获取列表 index 从1开始、列名、列类型、列的数据长度
|
||||
//System.out.println("aaa"+metaData.getColumnName(i)+"\t"+metaData.getColumnTypeName(i)+"\t"+metaData.getColumnDisplaySize(i));
|
||||
columnName.add(metaData.getColumnName(i));
|
||||
|
||||
}
|
||||
|
||||
while (rs.next()) {
|
||||
transportOneRecord(rs, metaData, columnNumber);
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
throw RdbmsException.asQueryException(dataBaseType, e, querySql, table, username);
|
||||
} finally {
|
||||
DBUtil.closeDBResources(null, conn);
|
||||
}
|
||||
////for(int i=0;i<columnNumber;i++){
|
||||
//columnName.add(metaData.getColumnName(i));
|
||||
//}//
|
||||
res=getResult(columnName);
|
||||
return new JsonPrimitive(res);
|
||||
}
|
||||
|
||||
private Record transportOneRecord(ResultSet rs, ResultSetMetaData metaData,
|
||||
int columnNumber) {
|
||||
Record record = buildRecord(rs, metaData, columnNumber);
|
||||
sendToWriter(record);
|
||||
return record;
|
||||
}
|
||||
|
||||
private void sendToWriter(Record record) {
|
||||
Validate.notNull(record, "record不能为空.");
|
||||
|
||||
record = doTransformer(record);
|
||||
|
||||
if (record == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buffer.add(record);
|
||||
}
|
||||
|
||||
private Record doTransformer(Record record) {
|
||||
System.out.println("Record"+record);
|
||||
if (transformerExecs == null || transformerExecs.size() == 0) {
|
||||
return record;
|
||||
}
|
||||
|
||||
ClassLoaderSwapper classLoaderSwapper = ClassLoaderSwapper
|
||||
.newCurrentThreadClassLoaderSwapper();
|
||||
|
||||
Record result = record;
|
||||
|
||||
String errorMsg = null;
|
||||
boolean failed = false;
|
||||
for (TransformerExecution transformerInfoExec : transformerExecs) {
|
||||
System.out.println("transformerExecs"+transformerInfoExec.getTransformerName());
|
||||
if (transformerInfoExec.getClassLoader() != null) {
|
||||
classLoaderSwapper.setCurrentThreadClassLoader(transformerInfoExec.getClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟检查transformer参数的有效性,直接抛出异常,不作为脏数据
|
||||
* 不需要在插件中检查参数的有效性。但参数的个数等和插件相关的参数,在插件内部检查
|
||||
*/
|
||||
if (!transformerInfoExec.isChecked()) {
|
||||
|
||||
if (transformerInfoExec.getColumnIndex() != null && transformerInfoExec.getColumnIndex() >= record.getColumnNumber()) {
|
||||
throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER,
|
||||
String.format("columnIndex[%s] out of bound[%s]. name=%s",
|
||||
transformerInfoExec.getColumnIndex(), record.getColumnNumber(),
|
||||
transformerInfoExec.getTransformerName()));
|
||||
}
|
||||
transformerInfoExec.setIsChecked(true);
|
||||
}
|
||||
|
||||
try {
|
||||
result = transformerInfoExec.getTransformer().evaluate(result, transformerInfoExec.gettContext(), transformerInfoExec.getFinalParas());
|
||||
} catch (Exception e) {
|
||||
errorMsg = String.format("transformer(%s) has Exception(%s)", transformerInfoExec.getTransformerName(),
|
||||
e.getMessage());
|
||||
failed = true;
|
||||
//LOG.error(errorMsg, e);
|
||||
// transformerInfoExec.addFailedRecords(1);
|
||||
//脏数据不再进行后续transformer处理,按脏数据处理,并过滤该record。
|
||||
break;
|
||||
|
||||
} finally {
|
||||
if (transformerInfoExec.getClassLoader() != null) {
|
||||
classLoaderSwapper.restoreCurrentThreadClassLoader();
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (failed) {
|
||||
return null;
|
||||
} else {
|
||||
System.out.println("result"+result);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Record buildRecord(ResultSet rs, ResultSetMetaData metaData,
|
||||
int columnNumber) {
|
||||
final byte[] EMPTY_CHAR_ARRAY = new byte[0];
|
||||
Record record = new DefaultRecord();
|
||||
try {
|
||||
for (int i = 1; i <= columnNumber; i++) {
|
||||
switch (metaData.getColumnType(i)) {
|
||||
|
||||
case Types.CHAR:
|
||||
case Types.NCHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.NVARCHAR:
|
||||
case Types.LONGNVARCHAR:
|
||||
case Types.CLOB:
|
||||
case Types.NCLOB:
|
||||
record.addColumn(new StringColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.SMALLINT:
|
||||
case Types.TINYINT:
|
||||
case Types.INTEGER:
|
||||
case Types.BIGINT:
|
||||
record.addColumn(new LongColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.NUMERIC:
|
||||
case Types.DECIMAL:
|
||||
record.addColumn(new DoubleColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.FLOAT:
|
||||
case Types.REAL:
|
||||
case Types.DOUBLE:
|
||||
record.addColumn(new DoubleColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.TIME:
|
||||
record.addColumn(new DateColumn(rs.getTime(i)));
|
||||
break;
|
||||
|
||||
// for mysql bug, see http://bugs.mysql.com/bug.php?id=35115
|
||||
case Types.DATE:
|
||||
if (metaData.getColumnTypeName(i).equalsIgnoreCase("year")) {
|
||||
record.addColumn(new LongColumn(rs.getInt(i)));
|
||||
} else {
|
||||
record.addColumn(new DateColumn(rs.getDate(i)));
|
||||
}
|
||||
break;
|
||||
|
||||
case Types.TIMESTAMP:
|
||||
record.addColumn(new DateColumn(rs.getTimestamp(i)));
|
||||
break;
|
||||
|
||||
case Types.BINARY:
|
||||
case Types.VARBINARY:
|
||||
case Types.BLOB:
|
||||
case Types.LONGVARBINARY:
|
||||
record.addColumn(new BytesColumn(rs.getBytes(i)));
|
||||
break;
|
||||
|
||||
// warn: bit(1) -> Types.BIT 可使用BoolColumn
|
||||
// warn: bit(>1) -> Types.VARBINARY 可使用BytesColumn
|
||||
case Types.BOOLEAN:
|
||||
case Types.BIT:
|
||||
record.addColumn(new BoolColumn(rs.getBoolean(i)));
|
||||
break;
|
||||
|
||||
case Types.NULL:
|
||||
String stringData = null;
|
||||
if (rs.getObject(i) != null) {
|
||||
stringData = rs.getObject(i).toString();
|
||||
}
|
||||
record.addColumn(new StringColumn(stringData));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw DataXException
|
||||
.asDataXException(
|
||||
DBUtilErrorCode.UNSUPPORTED_TYPE,
|
||||
String.format(
|
||||
"您的配置文件中的列配置信息有误. 因为DataX 不支持数据库读取这种字段类型. 字段名:[%s], 字段名称:[%s], 字段Java类型:[%s]. 请尝试使用数据库函数将其转换datax支持的类型 或者不同步该字段 .",
|
||||
metaData.getColumnName(i),
|
||||
metaData.getColumnType(i),
|
||||
metaData.getColumnClassName(i)));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e instanceof DataXException) {
|
||||
throw (DataXException) e;
|
||||
}
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
// private String recordToString(Record record) {
|
||||
// final String NEWLINE_FLAG = "\n";
|
||||
// String fieldDelimiter = "\t";
|
||||
//
|
||||
// int recordLength = record.getColumnNumber();
|
||||
// if (0 == recordLength) {
|
||||
// return NEWLINE_FLAG;
|
||||
// }
|
||||
//
|
||||
// Column column;
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (int i = 0; i < recordLength; i++) {
|
||||
// column = record.getColumn(i);
|
||||
// sb.append(column.asString()).append(fieldDelimiter);
|
||||
// }
|
||||
// sb.setLength(sb.length() - 1);
|
||||
// sb.append(NEWLINE_FLAG);
|
||||
//
|
||||
// return sb.toString();
|
||||
// }
|
||||
|
||||
public String getResult(ArrayList<String> columnName) {
|
||||
List<Object> dataList = new ArrayList<>();
|
||||
int size = buffer.size();
|
||||
//System.out.println("CCULUMN"+readerPara.getString(Key.COLUMN).toString());
|
||||
//String[] colmnNames = readerPara.getString(Key.COLUMN).replace(" ", "").split(",");
|
||||
int colmnSize= columnName.size();
|
||||
for (int i = 0; i < colmnSize; ++i) {
|
||||
Map<Object, Object> rowData = new HashMap<>();
|
||||
for (int j = 0; j < size; ++j) {
|
||||
rowData.put(columnName.get(i), buffer.get(j).getColumn(i).asString());
|
||||
}
|
||||
dataList.add(rowData);
|
||||
}
|
||||
|
||||
|
||||
return JsonUtil.toJson(dataList);
|
||||
}
|
||||
|
||||
}
|
||||
|
1309
src/main/java/org/bdware/sc/ContractProcess.java
Normal file
1309
src/main/java/org/bdware/sc/ContractProcess.java
Normal file
File diff suppressed because it is too large
Load Diff
122
src/main/java/org/bdware/sc/analysis/dynamic/FSAnalysis.java
Normal file
122
src/main/java/org/bdware/sc/analysis/dynamic/FSAnalysis.java
Normal file
@ -0,0 +1,122 @@
|
||||
package org.bdware.sc.analysis.dynamic;
|
||||
|
||||
import org.bdware.analysis.BasicBlock;
|
||||
import org.bdware.analysis.BreadthFirstSearch;
|
||||
import org.bdware.analysis.taint.*;
|
||||
import org.bdware.sc.bean.Contract;
|
||||
import org.bdware.sc.compiler.YJSCompiler;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.ContractZipBundle;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class FSAnalysis extends BreadthFirstSearch<TaintResult, TaintBB> {
|
||||
TaintCFG cfg;
|
||||
public static boolean isDebug = false;
|
||||
|
||||
public FSAnalysis(TaintCFG cfg) {
|
||||
this.cfg = cfg;
|
||||
List<TaintBB> toAnalysis = new ArrayList<>();
|
||||
// TODO add inputBlock!
|
||||
TaintBB b = (TaintBB) cfg.getBasicBlockAt(0);
|
||||
|
||||
b.preResult = new TaintResult();
|
||||
// local0=scriptfuncion, is not tainted;
|
||||
// local1=this, is not tainted;
|
||||
// local2=this, is not tainted;
|
||||
|
||||
b.preResult.frame.setLocal(0, HeapObject.getRootObject());
|
||||
b.preResult.frame.setLocal(1, new TaintValue(1, 0));
|
||||
b.preResult.frame.setLocal(2, new TaintValue(1, 1));
|
||||
|
||||
b.preResult.ret = new TaintValue(1);
|
||||
TaintResult.printer.setLabelOrder(cfg.getLabelOrder());
|
||||
toAnalysis.add(b);
|
||||
b.setInList(true);
|
||||
setToAnalysis(toAnalysis);
|
||||
if (isDebug) {
|
||||
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
|
||||
System.out.println(
|
||||
"===Local:"
|
||||
+ cfg.getMethodNode().maxLocals
|
||||
+ " "
|
||||
+ cfg.getMethodNode().maxStack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaintResult execute(TaintBB t) {
|
||||
return t.forwardAnalysis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<TaintBB> getSuc(TaintBB t) {
|
||||
Set<BasicBlock> subBlock = cfg.getSucBlocks(t);
|
||||
Set<TaintBB> ret = new HashSet<>();
|
||||
for (BasicBlock bb : subBlock) {
|
||||
TaintBB ntbb = (TaintBB) bb;
|
||||
ntbb.preResult.mergeResult(t.sucResult);
|
||||
ret.add(ntbb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String staticVerify(Contract c) {
|
||||
try {
|
||||
String script = c.getScriptStr();
|
||||
ContractNode cn = null;
|
||||
YJSCompiler compiler = new YJSCompiler();
|
||||
if (script.startsWith("/")) {
|
||||
String zipPath = script;
|
||||
ZipFile zf = new ZipFile(zipPath);
|
||||
ContractZipBundle czb = compiler.compile(zf);
|
||||
cn = czb.mergeContractNode();
|
||||
} else {
|
||||
cn =
|
||||
compiler.compile(
|
||||
new ByteArrayInputStream(script.getBytes()), "contract_main.yjs");
|
||||
}
|
||||
DesktopEngine engine = new DesktopEngine(); // engine.loadJar(zf);
|
||||
engine.loadContract(c, cn, false);
|
||||
Map<String, byte[]> clzs = engine.dumpClass(); // 拿到的类和对应的字节码
|
||||
Map<String, MethodNode> methods = new HashMap<>();
|
||||
for (byte[] clz : clzs.values()) {
|
||||
ClassNode classNode = new ClassNode();
|
||||
ClassReader cr = new ClassReader(clz);
|
||||
cr.accept(classNode, ClassReader.EXPAND_FRAMES);
|
||||
for (MethodNode mn : classNode.methods) {
|
||||
methods.put(mn.name, mn);
|
||||
}
|
||||
}
|
||||
Map<String, String> result = new HashMap<>();
|
||||
for (FunctionNode fn : cn.getFunctions()) {
|
||||
MethodNode mn = methods.get(fn.functionName);
|
||||
if (mn != null && mn.name.equals("statAge")) {
|
||||
System.out.println("[ContractManager] verify:" + fn.functionName);
|
||||
TaintResult.nLocals = mn.maxLocals;
|
||||
TaintResult.nStack = mn.maxStack;
|
||||
TaintCFG cfg = new TaintCFG(mn);
|
||||
TaintResult.printer.setLabelOrder(cfg.getLabelOrder());
|
||||
FSAnalysis analysis = new FSAnalysis(cfg);
|
||||
analysis.analysis();
|
||||
TaintBB bb = cfg.getLastBlock();
|
||||
if (bb != null) result.put(fn.functionName, bb.getResult());
|
||||
cfg.printSelf();
|
||||
}
|
||||
}
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
5
src/main/java/org/bdware/sc/blockdb/Constants.java
Normal file
5
src/main/java/org/bdware/sc/blockdb/Constants.java
Normal file
@ -0,0 +1,5 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
public class Constants {
|
||||
public static final int ELASTIC_DB = 0;
|
||||
}
|
13
src/main/java/org/bdware/sc/blockdb/DBRepository.java
Normal file
13
src/main/java/org/bdware/sc/blockdb/DBRepository.java
Normal file
@ -0,0 +1,13 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface DBRepository {
|
||||
public String Get(Map<String, Object> condition);//get hash of transaction
|
||||
public boolean Put(Transaction trans);//put transaction into databases
|
||||
public boolean Delete(String hash);//delete transaction
|
||||
public boolean Create_DB();//createDB
|
||||
public boolean Open_DB(); //OpenDB
|
||||
}
|
12
src/main/java/org/bdware/sc/blockdb/DBUtil.java
Normal file
12
src/main/java/org/bdware/sc/blockdb/DBUtil.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
public class DBUtil {
|
||||
private static DBRepository instance = null;
|
||||
|
||||
public static DBRepository getInstance(int type) {
|
||||
if (null == instance && type == Constants.ELASTIC_DB) {
|
||||
instance = new ElasticDBUtil();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
106
src/main/java/org/bdware/sc/blockdb/ElasticDBUtil.java
Normal file
106
src/main/java/org/bdware/sc/blockdb/ElasticDBUtil.java
Normal file
@ -0,0 +1,106 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import okhttp3.*;
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ElasticDBUtil implements DBRepository {
|
||||
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
public OkHttpClient client = new OkHttpClient();
|
||||
public List<Transaction> transactions = new ArrayList<>();
|
||||
public int bulk = 10000;
|
||||
|
||||
@Override
|
||||
public String Get(Map<String, Object> condition) {
|
||||
// TODO Auto-generated method stub
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
Map<String, Object> map1 = new HashMap<>();
|
||||
Map<String, String> map2 = new HashMap<>();
|
||||
map2.put("data", condition.get("data") + "*");
|
||||
map1.put("wildcard", map2);
|
||||
map.put("query", map1);
|
||||
String json = JsonUtil.toJson(map);
|
||||
RequestBody requestbody = FormBody.create(json, JSON);
|
||||
Request request = new Request.Builder().url("http://127.0.0.1:9200/transaction/_doc/_search").post(requestbody).build();
|
||||
try {
|
||||
Response resp = client.newCall(request).execute();
|
||||
System.out.print(resp.body().string());
|
||||
resp.body().close();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Put(Transaction trans) {
|
||||
// TODO Auto-generated method stub
|
||||
transactions.add(trans);
|
||||
if (transactions.size() == bulk) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
for (int i = 0; i < bulk; i++) {
|
||||
sb
|
||||
.append("{\"index\":{}}\n{\"data\":\"")
|
||||
.append(new String(transactions.get(i).data, StandardCharsets.UTF_8))
|
||||
.append("\",")
|
||||
.append("\"hash\":")
|
||||
.append("\"")
|
||||
.append(new String(transactions.get(i).hash, StandardCharsets.UTF_8))
|
||||
.append("\"")
|
||||
.append("}")
|
||||
.append("\n");
|
||||
}
|
||||
//System.out.println(sb.toString());
|
||||
RequestBody requestbody = FormBody.create(sb.toString(), JSON);
|
||||
Request request = new Request.Builder().url("http://127.0.0.1:9200/transaction/_doc/_bulk").post(requestbody).build();
|
||||
Response res1 = client.newCall(request).execute();
|
||||
boolean res = res1.isSuccessful();
|
||||
res1.body().close();
|
||||
System.out.println(res);
|
||||
transactions.clear();
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Delete(String hash) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Create_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
RequestBody body = RequestBody.create("", JSON);
|
||||
Request request = new Request.Builder().url("http://127.0.0.1:9200/transaction/").put(body).build();
|
||||
try {
|
||||
Response response = client.newCall(request).execute();
|
||||
boolean res = response.isSuccessful();
|
||||
response.body().close();
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Open_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
36
src/main/java/org/bdware/sc/blockdb/MongoDBUtil.java
Normal file
36
src/main/java/org/bdware/sc/blockdb/MongoDBUtil.java
Normal file
@ -0,0 +1,36 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MongoDBUtil {
|
||||
public static Object connect(String url, int port, String dbName, String usrName, String pwd) {
|
||||
try {
|
||||
Class serverAddr = Class.forName("com.mongodb.ServerAddress");
|
||||
Constructor cons = serverAddr.getConstructor(String.class, Integer.TYPE);
|
||||
Object serverAddress = cons.newInstance(url, port);
|
||||
List addrs = new ArrayList<>();
|
||||
addrs.add(serverAddress);
|
||||
Method createeScramSha1 =
|
||||
Class.forName("com.mongodb.MongoCredential")
|
||||
.getDeclaredMethod(
|
||||
"createScramSha1Credential",
|
||||
String.class,
|
||||
String.class,
|
||||
char[].class);
|
||||
Object credential = createeScramSha1.invoke(null, usrName, dbName, pwd.toCharArray());
|
||||
List credentials = new ArrayList<>();
|
||||
credentials.add(credential);
|
||||
Constructor mongoClient =
|
||||
Class.forName("com.mongodb.MongoClient").getConstructor(List.class, List.class);
|
||||
Object client = mongoClient.newInstance(addrs, credentials);
|
||||
// 通过连接认证获取MongoDB连接
|
||||
return client;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
72
src/main/java/org/bdware/sc/blockdb/RocksDBUtil.java
Normal file
72
src/main/java/org/bdware/sc/blockdb/RocksDBUtil.java
Normal file
@ -0,0 +1,72 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
import org.rocksdb.Options;
|
||||
import org.rocksdb.RocksDB;
|
||||
import org.rocksdb.RocksDBException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
public class RocksDBUtil implements DBRepository{
|
||||
private static RocksDB rocksdb;
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
public static RocksDB loadDB(String path, String readOnly) {
|
||||
try {
|
||||
Options options = new Options();
|
||||
options.setCreateIfMissing(true);
|
||||
RocksDB rocksDB;
|
||||
File lockFile = new File(path,"LOCK");
|
||||
lockFile.delete();
|
||||
if (readOnly != null && readOnly.equals("true")) {
|
||||
rocksDB = RocksDB.openReadOnly(options, path);
|
||||
} else
|
||||
rocksDB = RocksDB.open(options, path);
|
||||
rocksdb = rocksDB;
|
||||
return rocksDB;
|
||||
|
||||
} catch (RocksDBException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String Get(Map<String, Object> condition) {
|
||||
// TODO Auto-generated method stub
|
||||
if(condition.containsKey("start")&&condition.containsKey("end")) {
|
||||
int start = (int)condition.get("start");
|
||||
int end = (int)condition.get("end");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Put(Transaction trans) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Delete(String hash) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Create_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Open_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
117
src/main/java/org/bdware/sc/blockdb/SqliteDBUtil.java
Normal file
117
src/main/java/org/bdware/sc/blockdb/SqliteDBUtil.java
Normal file
@ -0,0 +1,117 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Block;
|
||||
import org.bdware.sc.commParser.BDLedger.BlockBody;
|
||||
import org.bdware.sc.commParser.BDLedger.BlockHeader;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
|
||||
public class SqliteDBUtil {
|
||||
private Connection conn;
|
||||
|
||||
public static SqliteDBUtil connect(String url) {
|
||||
try {
|
||||
String name = "org.sqlite.JDBC";
|
||||
SqliteDBUtil util = new SqliteDBUtil();
|
||||
String path = "jdbc:sqlite:";
|
||||
File file = new File(url);
|
||||
path = path + file.getAbsolutePath();
|
||||
System.out.println("[SqliteDBUtil] connect:" + path);
|
||||
Class.forName(name);
|
||||
util.conn = DriverManager.getConnection(path);
|
||||
return util;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BlockBody getBlockBody(String headerHash, String bodyHash) {
|
||||
try {
|
||||
Statement stmt = conn.createStatement();
|
||||
// ResultSet result = stmt.executeQuery("select * from BlockHeader where hash =
|
||||
// " + headerHash);
|
||||
String sql = "select * from BlockBody where ID = ?";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
pre.setBytes(1, HashUtil.str16ToBytes(bodyHash));
|
||||
ResultSet result = pre.executeQuery();
|
||||
// Assert we get only one!!!!
|
||||
while (result.next()) {
|
||||
System.out.println(result.getBytes("ID"));
|
||||
return BlockBody.fromBytes(result.getBytes("Data"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Block getBlock(String headerHash, String bodyHash) {
|
||||
try {
|
||||
BlockHeader header = new BlockHeader();
|
||||
BlockBody body = new BlockBody();
|
||||
Statement stmt = conn.createStatement();
|
||||
String sql = "select * from BlockBody where ID = ?";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
pre.setBytes(1, HashUtil.str16ToBytes(bodyHash));
|
||||
ResultSet result = pre.executeQuery();
|
||||
while (result.next()) {
|
||||
body = BlockBody.fromBytes(result.getBytes("Data"));
|
||||
}
|
||||
String sql1 = "select * from BlockHeader where Hash = ?";
|
||||
pre = conn.prepareStatement(sql1);
|
||||
pre.setBytes(1, HashUtil.str16ToBytes(headerHash));
|
||||
result = pre.executeQuery();
|
||||
while (result.next()) {
|
||||
header.index = result.getInt(1);
|
||||
header.hash = result.getBytes(2);
|
||||
header.version = result.getInt(3);
|
||||
header.timestamp = result.getInt(4);
|
||||
header.prevblockID = result.getBytes(5);
|
||||
header.merkleroot = result.getBytes(6);
|
||||
header.creatorID = result.getBytes(7);
|
||||
Block block = new Block(header,body);
|
||||
return block;
|
||||
//return Block.fromBytes(result.getBytes("Data"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public byte[] bodyselectall() {
|
||||
try {
|
||||
Statement stmt = conn.createStatement();
|
||||
// ResultSet result = stmt.executeQuery("select * from BlockHeader where hash =
|
||||
// " + headerHash);
|
||||
String sql = "select * from BlockBody limit 1,1";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
ResultSet result = pre.executeQuery();
|
||||
// Assert we get only one!!!!
|
||||
while (result.next()) {
|
||||
return result.getBytes(1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public byte[] headerselectall() {
|
||||
try {
|
||||
Statement stmt = conn.createStatement();
|
||||
// ResultSet result = stmt.executeQuery("select * from BlockHeader where hash =
|
||||
// " + headerHash);
|
||||
String sql = "select * from BlockHeader limit 1,1";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
ResultSet result = pre.executeQuery();
|
||||
// Assert we get only one!!!!
|
||||
while (result.next()) {
|
||||
return result.getBytes(2);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
39
src/main/java/org/bdware/sc/blockdb/TimeDBUtil.java
Normal file
39
src/main/java/org/bdware/sc/blockdb/TimeDBUtil.java
Normal file
@ -0,0 +1,39 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TimeDBUtil implements DBRepository{
|
||||
|
||||
@Override
|
||||
public String Get(Map<String, Object> condition) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Put(Transaction trans) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Delete(String hash) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Create_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Open_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
200
src/main/java/org/bdware/sc/boundry/AccountIndex.java
Normal file
200
src/main/java/org/bdware/sc/boundry/AccountIndex.java
Normal file
@ -0,0 +1,200 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import org.bdware.sc.boundry.TimeIndex.Data;
|
||||
import org.bdware.sc.index.LenVarTimeSerialIndex2;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.objects.NativeArray;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AccountIndex {
|
||||
static Map<String, LenVarTimeSerialIndex2> fileMap = new HashMap<>();
|
||||
|
||||
public static AccountIndex createIndex() {
|
||||
return new AccountIndex();
|
||||
}
|
||||
|
||||
private static String getString(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof String)) {
|
||||
return mem.toString();
|
||||
}
|
||||
return (String) mem;
|
||||
}
|
||||
|
||||
private static Integer getInteger(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof Integer)) {
|
||||
return Integer.valueOf(mem.toString());
|
||||
}
|
||||
return (Integer) mem;
|
||||
}
|
||||
|
||||
private static Long getLong(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof Long)) {
|
||||
return Long.valueOf(mem.toString());
|
||||
}
|
||||
return (Long) mem;
|
||||
}
|
||||
|
||||
public ScriptObject createFile(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("account")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("dataLength")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
Object file = args.get("file");
|
||||
if (!(file instanceof String)) {
|
||||
ret.put("result", "Illegal Type, file is not String", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
Object address = args.get("account");
|
||||
if (!(address instanceof String)) {
|
||||
ret.put("result", "Illegal Type, file is not String", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
String fileName = "./" + address + file;
|
||||
File f = new File(fileName + ".datasize");
|
||||
FileOutputStream fout = new FileOutputStream(f, false);
|
||||
Object dataLength = args.get("dataLength");
|
||||
int dataLengthInt = Integer.parseInt(dataLength.toString());
|
||||
for (int i = 0; i < dataLengthInt; i++)
|
||||
fout.write(1);
|
||||
fout.close();
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(fileName);
|
||||
ret.put("dataLength", dataLength, false);
|
||||
ret.put("datasize", f.length(), false);
|
||||
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Success", false);
|
||||
ret.put("result", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject requestByTime(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("account")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("startTime")) {
|
||||
ret.put("result", "Missing Argumemt: startTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("endTime")) {
|
||||
ret.put("result", "Missing Argumemt: endTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "account") + getString(args, "file"));
|
||||
long startTime = getLong(args, "startTime");
|
||||
long endTime = getLong(args, "endTime");
|
||||
List<byte[]> result = index.requestByTime(startTime, endTime);
|
||||
ret.put("status", "Success", false);
|
||||
NativeArray array = Global.allocate(new int[0]);
|
||||
ret.put("list", array, false);
|
||||
for (byte[] bytes : result) {
|
||||
JO data = new JO(PropertyMap.newMap());
|
||||
Data d = new Data(bytes);
|
||||
data.put("data", d.data, false);
|
||||
data.put("date", d.date, false);
|
||||
NativeArray.push(array, data);
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private LenVarTimeSerialIndex2 getIndexFile(String str) {
|
||||
LenVarTimeSerialIndex2 indexFile = fileMap.get(str);
|
||||
if (indexFile == null) {
|
||||
indexFile = new LenVarTimeSerialIndex2(str);
|
||||
fileMap.put(str, indexFile);
|
||||
}
|
||||
return indexFile;
|
||||
}
|
||||
|
||||
public ScriptObject manullyIndex(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("account")) {
|
||||
ret.put("result", "Missing Argumemt: account", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("date")) {
|
||||
ret.put("result", "Missing Argumemt: date", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("content")) {
|
||||
ret.put("result", "Missing Argumemt: content", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "account") + getString(args, "file"));
|
||||
long date = getLong(args, "date");
|
||||
String content = getString(args, "content");
|
||||
index.manullyIndex(date, HashUtil.str16ToBytes(content));
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
742
src/main/java/org/bdware/sc/boundry/JavaScriptEntry.java
Normal file
742
src/main/java/org/bdware/sc/boundry/JavaScriptEntry.java
Normal file
@ -0,0 +1,742 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.utils.SQLUtil;
|
||||
import org.bdware.sc.conn.ResultCallback;
|
||||
import org.bdware.sc.conn.SocketGet;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.engine.SyncMechUtil;
|
||||
import org.bdware.sc.event.REvent;
|
||||
import org.bdware.sc.http.ApiGate;
|
||||
import org.bdware.sc.syncMech.SyncType;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.zz.gmhelper.SM2KeyPair;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import javax.mail.*;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.Security;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static org.bdware.sc.event.REvent.REventType.*;
|
||||
|
||||
public class JavaScriptEntry {
|
||||
// private static final HostnameVerifier DO_NOT_VERIFY = (hostname, session) -> true;
|
||||
public static final Map<String, ScriptFunction> topic_handlers = new HashMap<>();
|
||||
private static final Logger LOGGER = LogManager.getLogger(JavaScriptEntry.class);
|
||||
public static NashornScriptEngine currentEngine;
|
||||
public static SyncMechUtil currentSyncUtil;
|
||||
// public static int contractManagerPort;
|
||||
public static Random random;
|
||||
public static long invokeID;
|
||||
public static String doi;
|
||||
public static String authInfoPersistDOI;
|
||||
public static SocketGet get; // public static CloseableHttpClient httpClient = getHttpClient();
|
||||
public static int numOfCopies;
|
||||
public static boolean isDebug;
|
||||
public static List<REvent> msgList;
|
||||
public static int shadingId;
|
||||
// private static SM2KeyPair keyPair = new SM2().generateKeyPair(); // TODO ?? 本地服务器的,39上运行39的
|
||||
// public static String privKey;
|
||||
// public static String pubKey;
|
||||
private static SM2KeyPair keyPair;
|
||||
|
||||
public static void setSM2KeyPair(String pubKey, String privKey) {
|
||||
keyPair =
|
||||
new SM2KeyPair(
|
||||
SM2KeyPair.publicKeyStr2ECPoint(pubKey), new BigInteger(privKey, 16));
|
||||
}
|
||||
|
||||
public static SM2KeyPair getKeyPair() {
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
public static Global getEngineGlobal() {
|
||||
return currentEngine.getNashornGlobal();
|
||||
}
|
||||
|
||||
public static String byteArrayHash(byte[] hash) {
|
||||
return HashUtil.hashByteArray(hash);
|
||||
}
|
||||
|
||||
public static Connection getMysqlConnection(String url, String usrName, String pwd) {
|
||||
return SQLUtil.getConnection("jdbc:mysql://" + url, usrName, pwd);
|
||||
}
|
||||
|
||||
public static String example(String arg) {
|
||||
LOGGER.debug("called: " + arg);
|
||||
return arg + 1;
|
||||
}
|
||||
|
||||
// public static MongoClient connectMongoDb(String url, int port, String dbName, String usrName,
|
||||
// String pwd) {
|
||||
// return getMongoDBConnection(url, port, dbName, usrName, pwd);
|
||||
// }
|
||||
//
|
||||
// public static MongoClient getMongoDBConnection(String url, int port, String dbName, String
|
||||
// usrName, String pwd) {
|
||||
// return MongoDBUtil.connect(url, port, dbName, usrName, pwd);
|
||||
// }
|
||||
|
||||
public static String bytes2Str(byte[] bytes) {
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
public static Object connectNeo4j(String url, String usrName, String pwd) {
|
||||
try {
|
||||
if (url.startsWith("jdbc:neo4j")) {
|
||||
Connection con;
|
||||
con = DriverManager.getConnection(url, usrName, pwd);
|
||||
return con;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static long currentTimeMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static Lock createLock() {
|
||||
return new ReentrantLock();
|
||||
}
|
||||
|
||||
public static String asyncTest(String str, ScriptFunction fun) {
|
||||
LOGGER.debug(str);
|
||||
DesktopEngine.applyWithGlobal(fun, currentEngine.getNashornGlobal(), str);
|
||||
return "success";
|
||||
}
|
||||
|
||||
// public static String http(String baseUrl, String method, Map<String, String> header,
|
||||
// Map<String, String> argMap,
|
||||
// List<String> reservedList) {
|
||||
// return HttpUtil.request(baseUrl, method, header, argMap, reservedList);
|
||||
// }
|
||||
|
||||
public static byte[] inputStreamToBytes(InputStream in) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
byte[] buff = new byte[4 * 1024 * 1024];
|
||||
try {
|
||||
for (int count; (count = in.read(buff)) > 0; ) {
|
||||
bo.write(buff, 0, count);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return bo.toByteArray();
|
||||
}
|
||||
|
||||
// private static String list2Str(List<String> reservedList) {
|
||||
// return JsonUtil.toJson(reservedList);
|
||||
// }
|
||||
//
|
||||
// private static String map2Str(Map<String, Object> map) {
|
||||
// return JsonUtil.toJson(map);
|
||||
// }
|
||||
|
||||
// private static CloseableHttpClient getHttpClient(String url) {
|
||||
// try {
|
||||
// SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
|
||||
//
|
||||
// @Override
|
||||
// public boolean isTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
|
||||
// throws java.security.cert.CertificateException {
|
||||
// return true;
|
||||
// }
|
||||
// }).build();
|
||||
//
|
||||
// SSLConnectionSocketFactory sslSf = new SSLConnectionSocketFactory(sslcontext, null, null,
|
||||
// new NoopHostnameVerifier());
|
||||
// int tle = 10;
|
||||
// if (url.contains("data.tj.gov.cn"))
|
||||
// tle = 3;
|
||||
// return HttpClients.custom().setSSLSocketFactory(sslSf)
|
||||
// .setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
|
||||
// @Override
|
||||
// public long getKeepAliveDuration(HttpResponse arg0, HttpContext arg1) {
|
||||
// return 0;
|
||||
// }
|
||||
// }).setConnectionTimeToLive(tle, TimeUnit.SECONDS).build();
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public static InputStream httpAsInputStream(String url) {
|
||||
try {
|
||||
URL realUrl = new URL(url);
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
return conn.getInputStream();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// public static String httpPost(String str) {
|
||||
// System.out.println("JavaSScriptEntry httpPost:" + str);
|
||||
// PostRequest req = new PostRequest();
|
||||
// req = JsonUtil.fromJson(str, PostRequest.class);
|
||||
// // System.out.println("url========>" + req.url);
|
||||
// // System.out.println("data=======>" + req.data);
|
||||
//
|
||||
// Result r = new Result();
|
||||
// try {
|
||||
// URL url = new URL(req.url);//
|
||||
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
// connection.setDoOutput(true);
|
||||
// connection.setDoInput(true);
|
||||
// connection.setUseCaches(false);
|
||||
// connection.setInstanceFollowRedirects(true);
|
||||
// connection.setRequestMethod("POST"); // 璁剧疆璇锋眰鏂瑰紡
|
||||
// connection.setRequestProperty("Accept", "application/json"); // 璁剧疆鎺ユ敹鏁版嵁鐨勬牸寮<EFBFBD>
|
||||
// connection.setRequestProperty("Content-Type", "application/json"); // 璁剧疆鍙戦<EFBFBD>佹暟鎹殑鏍煎紡
|
||||
// connection.connect();
|
||||
// OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); //
|
||||
// utf-8缂栫爜
|
||||
// out.append(req.data);
|
||||
// out.flush();
|
||||
// out.close();
|
||||
//
|
||||
// r.resposeCode = connection.getResponseCode();
|
||||
// InputStream input = connection.getInputStream();
|
||||
//
|
||||
// Scanner sc = new Scanner(input);
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (; sc.hasNextLine();) {
|
||||
// sb.append(sc.nextLine()).append("\n");
|
||||
// }
|
||||
// sc.close();
|
||||
// r.response = sb.toString();
|
||||
// return JsonUtil.toJson(r);
|
||||
// } catch (Throwable e) {
|
||||
// r.resposeCode = 505;
|
||||
// // ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// // e.printStackTrace(new PrintStream(bo));
|
||||
// r.response = e.getMessage();
|
||||
// return JsonUtil.toJson(r);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static void executeFunction(ScriptFunction callback, Object arg) {
|
||||
DesktopEngine.applyWithGlobal(callback, currentEngine.getNashornGlobal(), arg);
|
||||
}
|
||||
|
||||
public static ApiGate createAPIGate(String ip) {
|
||||
return new ApiGate(ip);
|
||||
}
|
||||
|
||||
public static ApiGate createAPIGate(String ip, String port) {
|
||||
return new ApiGate(ip, Integer.parseInt(port));
|
||||
}
|
||||
|
||||
public static String executeContractWithSig(
|
||||
String contractID, String action, String arg, String pubkey, String sig) {
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.setPublicKey(pubkey);
|
||||
app.setSignature(sig);
|
||||
app.fromContract = keyPair.getPublicKeyStr();
|
||||
if (!app.verifySignature()) {
|
||||
return "{\"status\":\"Exception\",\"data\":\"invalid signature\"}";
|
||||
}
|
||||
app.setRequesterDOI(doi);
|
||||
app.setFromDebug(isDebug);
|
||||
if (numOfCopies > 1) {
|
||||
// The caller is special.
|
||||
app.setRequestID(
|
||||
app.getPublicKey().hashCode()
|
||||
+ "_"
|
||||
+ numOfCopies
|
||||
+ "_"
|
||||
+ (invokeID++)
|
||||
+ "_"
|
||||
+ random.nextInt()
|
||||
+ "_mul");
|
||||
} else {
|
||||
app.setRequestID(
|
||||
app.getPublicKey().hashCode()
|
||||
+ "_"
|
||||
+ (invokeID++)
|
||||
+ "_"
|
||||
+ random.nextInt());
|
||||
}
|
||||
return get.syncGet("dd", "executeContract", JsonUtil.toJson(app));
|
||||
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
return bo.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static String executeContract(String contractID, String action, String arg) {
|
||||
if (currentSyncUtil.engine.recovering) {
|
||||
String str =
|
||||
currentSyncUtil.transRecoverUtil.curRecoverRecord.getExecuteResult(
|
||||
invokeID + "");
|
||||
String[] strs = str.split("<seperate>");
|
||||
String flag1 = strs[0];
|
||||
String flag = strs[1];
|
||||
String res = strs[2];
|
||||
if (flag1.equals("1")) {
|
||||
invokeID++;
|
||||
}
|
||||
if (flag.equals("1")) {
|
||||
random.nextInt();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
long formerInvokeID = invokeID;
|
||||
int flag1 = 0; // 标志invokeID++操作是否进行过
|
||||
int flag = 0; // 标志random是否取下一个
|
||||
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.doSignature(keyPair);
|
||||
app.setRequesterDOI(doi);
|
||||
app.setFromDebug(isDebug);
|
||||
if (numOfCopies > 1) {
|
||||
app.setRequestID(
|
||||
String.format(
|
||||
"%d_%d_%d_%d_mul",
|
||||
keyPair.getPublicKeyStr().hashCode(),
|
||||
numOfCopies,
|
||||
(invokeID++),
|
||||
random.nextInt()));
|
||||
// The caller is special.
|
||||
flag = 1;
|
||||
flag1 = 1;
|
||||
LOGGER.warn("invoke contractExecution! " + JsonUtil.toJson(app));
|
||||
} else {
|
||||
app.setRequestID(
|
||||
String.format(
|
||||
"%d_%d_%d",
|
||||
keyPair.getPublicKeyStr().hashCode(),
|
||||
(invokeID++),
|
||||
random.nextInt()));
|
||||
flag = 1;
|
||||
flag1 = 1;
|
||||
}
|
||||
return executeContract(formerInvokeID, flag1, flag, app);
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
String result = bo.toString();
|
||||
if (currentSyncUtil.startFlag
|
||||
&& currentSyncUtil.currType == SyncType.Trans
|
||||
&& !currentSyncUtil.engine.recovering) {
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(
|
||||
formerInvokeID + "", flag1 + "<seperate>" + flag + "<seperate>" + result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static String executeContract(long formerInvokeID, int flag1, int flag, ContractRequest app) {
|
||||
String result = get.syncGet("dd", "executeContract", JsonUtil.toJson(app));
|
||||
if (currentSyncUtil.startFlag
|
||||
&& currentSyncUtil.currType == SyncType.Trans
|
||||
&& !currentSyncUtil.engine.recovering) {
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(
|
||||
formerInvokeID + "",
|
||||
flag1 + "<seperate>" + flag + "<seperate>" + result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void executeContractAsyncWithoutSig(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.setRequestID((invokeID++) + "_" + random.nextInt());
|
||||
get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (null != cb) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, currentEngine.getNashornGlobal(), str);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
}
|
||||
}
|
||||
|
||||
/* public static String executeContract(String contractID, String action, String arg) {
|
||||
//redo,use record data
|
||||
if(currentSyncUtil.transRecoverUtil != null && currentSyncUtil.transRecoverUtil.recovering){
|
||||
String k = TransRecordUtil.produceExecuteIdentifier(contractID,action,arg);
|
||||
return currentSyncUtil.transRecoverUtil.curRecoverRecord.getExecuteResult(k);
|
||||
}
|
||||
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
//app.doSignature(keyPair.getPrivateKey().toString(16));
|
||||
app.doSignature(keyPair);
|
||||
String result = get.syncGet("dd", "executeContract", JsonUtil.toJson(app));
|
||||
if(currentSyncUtil.startFlag && currentSyncUtil.currType == SyncType.Trans){
|
||||
String k = currentSyncUtil.transRecordUtil.produceExecuteIdentifier(contractID,action,arg);
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(k,result);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
String result = bo.toString();
|
||||
if(currentSyncUtil.startFlag && currentSyncUtil.currType == SyncType.Trans){
|
||||
String k = TransRecordUtil.produceExecuteIdentifier(contractID,action,arg);
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(k,result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}*/
|
||||
|
||||
// public static String queryContractIdByDOI(String contractDOI) throws Exception {
|
||||
// DigitalObject contractDO;
|
||||
// DoipClient doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// DOIPMainServer.repoUrl, DoipMessageFormat.PACKET.getName());
|
||||
// DoMessage response = doipClient.retrieve(contractDOI, null, null);
|
||||
// if (response.parameters.response == DoResponse.Success) {
|
||||
// contractDO = DigitalObject.parse(response.body);
|
||||
// } else {
|
||||
// response = DOAClient.getGlobalInstance().retrieve(contractDOI, null, null);
|
||||
// contractDO = DigitalObject.parse(response.body);
|
||||
// }
|
||||
// ContractInstanceDO contractInstanceDO =
|
||||
// (ContractInstanceDO)
|
||||
// ContractManager.toObject(contractDO.elements.get(0).getData());
|
||||
// return contractInstanceDO.id;
|
||||
// }
|
||||
|
||||
// public static String executeContractByDOI(String contractDOI, String action, String arg) {
|
||||
// try {
|
||||
// String contractID = queryContractIdByDOI(contractDOI);
|
||||
// return executeContract(contractID, action, arg);
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// return bo.toString();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static String getAuthInfo() {
|
||||
// try {
|
||||
// DigitalObject contractDO;
|
||||
// DoipClient doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// DOIPMainServer.repoUrl, DoipMessageFormat.PACKET.getName());
|
||||
// DoMessage response = doipClient.retrieve(authInfoPersistDOI, null, null);
|
||||
// if (response.parameters.response != DoResponse.Success) {
|
||||
// response = DOAClient.getGlobalInstance().retrieve(authInfoPersistDOI, null,
|
||||
// null);
|
||||
// }
|
||||
// contractDO = DigitalObject.parse(response.body);
|
||||
// return new String(contractDO.elements.get(0).getData());
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// return "Failed: " + bo.toString();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static String setAuthInfo(String authInfo) {
|
||||
// try {
|
||||
//
|
||||
// DigitalObject contractDO = new DigitalObject(authInfoPersistDOI, DoType.Json);
|
||||
// Element e = new Element("authInfo", "JsonString");
|
||||
// e.setData(authInfo.getBytes());
|
||||
// contractDO.addElements(e);
|
||||
//
|
||||
// DoipClient doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// DOIPMainServer.repoUrl, DoipMessageFormat.PACKET.getName());
|
||||
// DoMessage response = doipClient.update(contractDO);
|
||||
// if (response.parameters.response != DoResponse.Success) {
|
||||
// DoHandleRecord dohr =
|
||||
// DOAClient.getGlobalInstance().resolveDO(authInfoPersistDOI);
|
||||
// if (dohr == null) {
|
||||
// return "Failed: Can not resolve authInfoPersistDOI: " +
|
||||
// authInfoPersistDOI;
|
||||
// }
|
||||
// ServiceHandleRecord repoHandleRecord =
|
||||
// DOAClient.getGlobalInstance().resolveDOIPService(dohr.repository);
|
||||
// doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// repoHandleRecord.getListenerInfos().get(0).url,
|
||||
// DoipMessageFormat.PACKET.getName());
|
||||
// response = doipClient.update(contractDO);
|
||||
// if (response.parameters.response != DoResponse.Success) {
|
||||
// return "Failed: Can not update authInfoPersistDOI: " + authInfoPersistDOI;
|
||||
// }
|
||||
// }
|
||||
// return "Succeeded";
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// return "Failed: " + bo.toString();
|
||||
// }
|
||||
// }
|
||||
|
||||
public static String executeContractAsync(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.doSignature(keyPair);
|
||||
app.setRequestID((invokeID++) + "_" + random());
|
||||
app.setRequesterDOI(doi);
|
||||
get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (cb != null) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, currentEngine.getNashornGlobal(), str, arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
return bo.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* publish an event with semantic AT_LEAST_ONCE
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param content the content
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void pubEvent(String topic, String content) {
|
||||
pubEventConstraint(topic, content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* publish an event with some semantic
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param content the content
|
||||
* @param constraint the constraint, AT_LEAST_ONCE, AT_MOST_ONCE, and ONLY_ONCE
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void pubEventConstraint(String topic, String content, String constraint) {
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_pe",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, invokeID, random());
|
||||
REvent msg = new REvent(topic, PUBLISH, content, reqID);
|
||||
if (null != constraint) {
|
||||
msg.setSemantics(REvent.REventSemantics.valueOf(constraint));
|
||||
}
|
||||
msgList.add(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* subscribe a topic
|
||||
*
|
||||
* @param topic event topic
|
||||
* @param fun related handler function
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void subscribe(String topic, ScriptFunction fun) {
|
||||
subscribe(topic, fun, false);
|
||||
if (topic_handlers.containsKey(topic)) {
|
||||
ContractProcess.instance.unSubscribe(topic_handlers.get(topic).getName());
|
||||
}
|
||||
topic_handlers.put(topic, fun);
|
||||
}
|
||||
|
||||
private static void subscribe(String topic, ScriptFunction fun, boolean fromPreSub) {
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_se",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, invokeID, random());
|
||||
|
||||
REvent msg =
|
||||
new REvent(
|
||||
topic,
|
||||
SUBSCRIBE,
|
||||
String.format(
|
||||
"{\"subscriber\":\"%s\",\"handler\":\"%s\"}",
|
||||
ContractProcess.instance.getContractName(), fun.getName()),
|
||||
reqID);
|
||||
if (fromPreSub) {
|
||||
msg.setSemantics(REvent.REventSemantics.ONLY_ONCE);
|
||||
}
|
||||
msgList.add(msg);
|
||||
|
||||
ContractProcess.instance.subscribe(fun.getName());
|
||||
}
|
||||
|
||||
public static void unsubscribe(String topic) {
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_us",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, invokeID, random());
|
||||
String content;
|
||||
if (null == topic) {
|
||||
content = "{\"subscriber\":\"" + ContractProcess.instance.getContractName() + "\"}";
|
||||
topic_handlers.forEach((k, c) -> {
|
||||
topic_handlers.remove(k);
|
||||
ContractProcess.instance.unSubscribe(c.getName());
|
||||
});
|
||||
} else {
|
||||
String handler = topic_handlers.get(topic).getName();
|
||||
content =
|
||||
String.format(
|
||||
"{\"subscriber\":\"%s\",\"handler\":\"%s\"}",
|
||||
ContractProcess.instance.getContractName(), handler);
|
||||
topic_handlers.remove(topic);
|
||||
ContractProcess.instance.unSubscribe(handler);
|
||||
}
|
||||
REvent msg =
|
||||
new REvent(
|
||||
topic,
|
||||
UNSUBSCRIBE,
|
||||
content,
|
||||
reqID);
|
||||
msgList.add(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* pre-sub in ONLY_ONCE
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param content the content
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void preSub(String topic, String content) {
|
||||
String newTopic = topic + "|" + content + "|" + ContractProcess.instance.getContractName();
|
||||
subscribe(newTopic, topic_handlers.get(topic), true);
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_pse",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, (invokeID++), random());
|
||||
REvent msg = new REvent(topic, REvent.REventType.PRESUB, newTopic, reqID);
|
||||
msg.setSemantics(REvent.REventSemantics.ONLY_ONCE);
|
||||
msgList.add(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random value with string format
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static String random() {
|
||||
String seed = String.valueOf(null == random ? System.currentTimeMillis() : random.nextInt());
|
||||
return HashUtil.sha3(seed);
|
||||
}
|
||||
|
||||
public static String getContractInfo(String topic) {
|
||||
return null;
|
||||
// TODO
|
||||
}
|
||||
|
||||
public static String sendEmail(String json) {
|
||||
try {
|
||||
final JsonObject jo = JsonParser.parseString(json).getAsJsonObject();
|
||||
Properties props = new Properties();
|
||||
props.setProperty("mail.debug", "false");
|
||||
props.setProperty("mail.smtp.auth", "true");
|
||||
props.setProperty("mail.smtp.host", jo.get("host").getAsString());
|
||||
props.setProperty("mail.smtp.port", jo.get("port").getAsString());
|
||||
props.setProperty("mail.transport.protocol", "smtp");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
|
||||
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
|
||||
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
|
||||
props.setProperty("mail.smtp.socketFactory.fallback", "false");
|
||||
props.setProperty("mail.smtp.socketFactory.port", jo.get("port").getAsString());
|
||||
Session session =
|
||||
Session.getDefaultInstance(
|
||||
props,
|
||||
new Authenticator() {
|
||||
public PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(
|
||||
jo.get("from").getAsString(),
|
||||
jo.get("pwd").getAsString()); // 发件人邮件用户名、密码
|
||||
}
|
||||
});
|
||||
// 创建邮件对象
|
||||
|
||||
Message msg = new MimeMessage(session);
|
||||
msg.setSubject(jo.get("subject").getAsString());
|
||||
msg.setText(jo.get("content").getAsString());
|
||||
msg.setFrom(new InternetAddress(jo.get("from").getAsString()));
|
||||
msg.addRecipient(
|
||||
Message.RecipientType.TO, new InternetAddress(jo.get("to").getAsString()));
|
||||
Transport.send(msg);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "failed";
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
public static ScriptObject getCaller(int i) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
|
||||
if (stacktrace.length > i + 2) {
|
||||
ret.put("name", stacktrace[i + 2].getMethodName(), false);
|
||||
ret.put("file", stacktrace[i + 2].getFileName(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
public int responseCode;
|
||||
public String response;
|
||||
}
|
||||
|
||||
static class PostRequest {
|
||||
String url;
|
||||
String data;
|
||||
}
|
||||
}
|
93
src/main/java/org/bdware/sc/boundry/Resources.java
Normal file
93
src/main/java/org/bdware/sc/boundry/Resources.java
Normal file
@ -0,0 +1,93 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import org.bdware.sc.engine.YJSClassLoader;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import java.util.zip.ZipInputStream;
|
||||
public class Resources {
|
||||
private final ZipFile zf;
|
||||
YJSClassLoader loader;
|
||||
|
||||
public Resources(ZipFile zf, YJSClassLoader loader) {
|
||||
this.zf = zf;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public InputStream loadAsInputStream(String path) {
|
||||
try {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
if (entry == null)
|
||||
return null;
|
||||
return zf.getInputStream(entry);
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Scanner loadAsScanner(String path) {
|
||||
try {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
if (entry == null)
|
||||
return null;
|
||||
return new Scanner(zf.getInputStream(entry));
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String loadAsString(String path) {
|
||||
try {
|
||||
InputStream sc = loadAsInputStream(path);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
byte[] buff = new byte[1024];
|
||||
for (int k = 0; (k = sc.read(buff)) > 0; ) {
|
||||
bo.write(buff, 0, k);
|
||||
}
|
||||
return new String(bo.toByteArray());
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<?> testloadAsScanner(String path) {
|
||||
BufferedReader reader;
|
||||
List<String> fileList = new ArrayList<>();
|
||||
try {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
if (entry == null)
|
||||
return null;
|
||||
reader = new BufferedReader(new InputStreamReader(zf.getInputStream(entry), StandardCharsets.UTF_8));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
fileList.add(line);
|
||||
// System.out.println(line);
|
||||
}
|
||||
return fileList;
|
||||
// return new ArrayList<>();
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String unzipToDir(String path) {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
try {
|
||||
return loader.unzipLibrary(zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
306
src/main/java/org/bdware/sc/boundry/TimeIndex.java
Normal file
306
src/main/java/org/bdware/sc/boundry/TimeIndex.java
Normal file
@ -0,0 +1,306 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import org.bdware.sc.index.LenVarTimeSerialIndex2;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.objects.NativeArray;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TimeIndex {
|
||||
static Map<String, LenVarTimeSerialIndex2> fileMap = new HashMap<>();
|
||||
|
||||
public static TimeIndex createIndex() {
|
||||
return new TimeIndex();
|
||||
}
|
||||
|
||||
private static String getString(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof String)) {
|
||||
return mem.toString();
|
||||
}
|
||||
return (String) mem;
|
||||
}
|
||||
|
||||
private static Integer getInteger(ScriptObjectMirror obj) {
|
||||
Object mem = obj.getMember("count");
|
||||
if (mem != null && !(mem instanceof Integer)) {
|
||||
return Integer.valueOf(mem.toString());
|
||||
}
|
||||
return (Integer) mem;
|
||||
}
|
||||
|
||||
private static Long getLong(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof Long)) {
|
||||
return Long.valueOf(mem.toString());
|
||||
}
|
||||
return (Long) mem;
|
||||
}
|
||||
|
||||
public ScriptObject createFile(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("dataLength")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
Object file = args.get("file");
|
||||
if (!(file instanceof String)) {
|
||||
ret.put("result", "Illegal Type, file is not String", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
String fileName = "./" + file;
|
||||
File f = new File(fileName + ".datasize");
|
||||
FileOutputStream fout = new FileOutputStream(f, false);
|
||||
Object dataLength = args.get("dataLength");
|
||||
int dataLengthInt = Integer.parseInt(dataLength.toString());
|
||||
for (int i = 0; i < dataLengthInt; i++)
|
||||
fout.write(1);
|
||||
fout.close();
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(fileName);
|
||||
ret.put("dataLength", dataLength, false);
|
||||
ret.put("datasize", f.length(), false);
|
||||
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Success", false);
|
||||
ret.put("result", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject index(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("content")) {
|
||||
ret.put("result", "Missing Argumemt: content", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
String content = getString(args, "content");
|
||||
long result = index.index(HashUtil.str16ToBytes(content));
|
||||
ret.put("date", result, false);
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("exception", bo.toString(), false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject dataSize(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
ret.put("fileSize", index.fileSize, false);
|
||||
ret.put("dataSize", index.dataSize, false);
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("exception", bo.toString(), false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject requestByTime(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("startTime")) {
|
||||
ret.put("result", "Missing Argumemt: startTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("endTime")) {
|
||||
ret.put("result", "Missing Argumemt: endTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
long startTime = getLong(args, "startTime");
|
||||
long endTime = getLong(args, "endTime");
|
||||
List<byte[]> result = index.requestByTime(startTime, endTime);
|
||||
ret.put("status", "Success", false);
|
||||
NativeArray array = Global.allocate(new int[0]);
|
||||
ret.put("list", array, false);
|
||||
for (byte[] bytes : result) {
|
||||
JO data = new JO(PropertyMap.newMap());
|
||||
Data d = new Data(bytes);
|
||||
data.put("data", d.data, false);
|
||||
data.put("date", d.date, false);
|
||||
NativeArray.push(array, data);
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject request(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("offset")) {
|
||||
ret.put("result", "Missing Argumemt: offset", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("count")) {
|
||||
ret.put("result", "Missing Argumemt: count", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
long offset = getLong(args, "offset");
|
||||
int count = getInteger(args);
|
||||
List<byte[]> result = index.request(offset, count);
|
||||
ret.put("status", "Success", false);
|
||||
NativeArray array = Global.allocate(new int[0]);
|
||||
ret.put("list", array, false);
|
||||
for (byte[] bytes : result) {
|
||||
JO data = new JO(PropertyMap.newMap());
|
||||
Data d = new Data(bytes);
|
||||
data.put("data", d.data, false);
|
||||
data.put("date", d.date, false);
|
||||
NativeArray.push(array, data);
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject getSize(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
int size = (int) index.size();
|
||||
ret.put("status", "Success", false);
|
||||
ret.put("size", size, false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private LenVarTimeSerialIndex2 getIndexFile(String str) {
|
||||
LenVarTimeSerialIndex2 indexFile = fileMap.get(str);
|
||||
if (indexFile == null) {
|
||||
indexFile = new LenVarTimeSerialIndex2(str);
|
||||
fileMap.put(str, indexFile);
|
||||
}
|
||||
return indexFile;
|
||||
}
|
||||
|
||||
public ScriptObject manuallyIndex(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("date")) {
|
||||
ret.put("result", "Missing Argumemt: date", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("content")) {
|
||||
ret.put("result", "Missing Argumemt: content", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
long date = getLong(args, "date");
|
||||
String content = getString(args, "content");
|
||||
index.manullyIndex(date, HashUtil.str16ToBytes(content));
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static class Data {
|
||||
long date;
|
||||
String data;
|
||||
|
||||
public Data(byte[] bytes) {
|
||||
date = HashUtil.bytes2Long(bytes);
|
||||
data = HashUtil.byteArray2Str(bytes, 8);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
50
src/main/java/org/bdware/sc/boundry/utils/AESUtil.java
Normal file
50
src/main/java/org/bdware/sc/boundry/utils/AESUtil.java
Normal file
@ -0,0 +1,50 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@PermissionStub(permission = Permission.AES)
|
||||
public class AESUtil {
|
||||
public static ScriptObject encrypt(String key, String plaintext) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
String iv = generateKey(128);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(DatatypeConverter.parseHexBinary(iv));
|
||||
byte[] byteContent = plaintext.getBytes();
|
||||
SecretKeySpec secretKeySpecSpec = new SecretKeySpec(DatatypeConverter.parseHexBinary(key), "AES");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpecSpec, ivSpec);
|
||||
byte[] result = cipher.doFinal(byteContent);
|
||||
ret.put("iv", iv, false);
|
||||
ret.put("cipherText", DatatypeConverter.printHexBinary(result).toLowerCase(), false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String decrypt(String key, String ciphertext, String iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||
// JO ret = new JO(PropertyMap.newMap());
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(DatatypeConverter.parseHexBinary(iv));
|
||||
byte[] byteContent = DatatypeConverter.parseHexBinary(ciphertext);
|
||||
SecretKeySpec secretKeySpecSpec = new SecretKeySpec(DatatypeConverter.parseHexBinary(key), "AES");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpecSpec, ivSpec);
|
||||
byte[] result = cipher.doFinal(byteContent);
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
public static String generateKey(int bit) throws NoSuchAlgorithmException {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
keyGenerator.init(bit);
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
return DatatypeConverter.printHexBinary(secretKey.getEncoded()).toLowerCase();
|
||||
}
|
||||
}
|
117
src/main/java/org/bdware/sc/boundry/utils/AsyncUtil.java
Normal file
117
src/main/java/org/bdware/sc/boundry/utils/AsyncUtil.java
Normal file
@ -0,0 +1,117 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.conn.ResultCallback;
|
||||
import org.bdware.sc.conn.ServiceServer;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
@PermissionStub(permission = Permission.Async)
|
||||
public class AsyncUtil {
|
||||
private static final Timer TIMER = new Timer();
|
||||
// public static ExecutorService executorService = Executors.newFixedThreadPool(10);
|
||||
|
||||
public static String sleep(long sleep) {
|
||||
try {
|
||||
Thread.sleep(sleep);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
public static String postFunction(final ScriptFunction callback, Object wrapper) {
|
||||
ServiceServer.executor.execute(
|
||||
() -> JavaScriptEntry.executeFunction(callback, wrapper));
|
||||
return "success";
|
||||
}
|
||||
|
||||
public static TimerTask setTimeOut(
|
||||
final ScriptFunction callback, long delay, final Object arg) {
|
||||
TimerTask task =
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
JavaScriptEntry.executeFunction(callback, arg);
|
||||
}
|
||||
};
|
||||
TIMER.schedule(task, delay);
|
||||
return task;
|
||||
}
|
||||
|
||||
public static TimerTask setInterval(
|
||||
final ScriptFunction callback, long delay, long interval, final Object arg) {
|
||||
TimerTask task =
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
JavaScriptEntry.executeFunction(callback, arg);
|
||||
}
|
||||
};
|
||||
TIMER.schedule(task, delay, interval);
|
||||
return task;
|
||||
}
|
||||
|
||||
public static void executeContractAsyncWithoutSig(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.setRequestID((JavaScriptEntry.invokeID++) + "_" + JavaScriptEntry.random.nextInt());
|
||||
JavaScriptEntry.get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (null != cb) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, JavaScriptEntry.currentEngine.getNashornGlobal(), str);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
}
|
||||
}
|
||||
public static String executeContractAsync(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.doSignature(JavaScriptEntry.getKeyPair());
|
||||
app.setRequestID((JavaScriptEntry.invokeID++) + "_" + JavaScriptEntry.random());
|
||||
app.setRequesterDOI(JavaScriptEntry.doi);
|
||||
JavaScriptEntry.get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (cb != null) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, JavaScriptEntry.currentEngine.getNashornGlobal(), str, arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
return bo.toString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.db.TimeDBUtil;
|
||||
import org.bdware.sc.db.TimeRocksDBUtil;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@PermissionStub(permission = Permission.BDWareTimeSeriesDB)
|
||||
public class BDWareTimeSeriesDBUtil {
|
||||
public static TimeRocksDBUtil getConnection() {
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
parent = new File(parent, "BDWareTimeSeriesDB");
|
||||
return new TimeRocksDBUtil(parent.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static TimeRocksDBUtil getConnection(String dbName) {
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
parent = new File(parent, dbName);
|
||||
return new TimeRocksDBUtil(parent.getAbsolutePath());
|
||||
}
|
||||
}
|
12
src/main/java/org/bdware/sc/boundry/utils/CMUtil.java
Normal file
12
src/main/java/org/bdware/sc/boundry/utils/CMUtil.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
@PermissionStub(permission = Permission.CM)
|
||||
public class CMUtil {
|
||||
public static String getTimesOfExecution(String contractName) {
|
||||
return JavaScriptEntry.get.syncGet("", "getTimesOfExecution", contractName);
|
||||
}
|
||||
}
|
192
src/main/java/org/bdware/sc/boundry/utils/DOIPUtil.java
Normal file
192
src/main/java/org/bdware/sc/boundry/utils/DOIPUtil.java
Normal file
@ -0,0 +1,192 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bdware.doip.application.client.ContractDOAClient;
|
||||
import org.bdware.doip.core.doipMessage.DoipMessage;
|
||||
import org.bdware.doip.core.exception.DoDecodeException;
|
||||
import org.bdware.doip.core.exception.IrpClientException;
|
||||
import org.bdware.doip.core.model.digitalObject.DigitalObject;
|
||||
import org.bdware.doip.core.model.digitalObject.Element;
|
||||
import org.bdware.doip.core.utils.DoipGson;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@PermissionStub(permission = Permission.DOIP)
|
||||
public class DOIPUtil {
|
||||
// private static final Logger LOGGER = LogManager.getLogger(DOIPUtil.class);
|
||||
public static ContractDOAClient doaClient = null;
|
||||
|
||||
static {
|
||||
initClient();
|
||||
}
|
||||
|
||||
public static String test(String doi) {
|
||||
return "create DOClient And hello " + doi + " World";
|
||||
}
|
||||
|
||||
public static String hello(String repoID) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.hello(repoID);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String retrieve(String doi, String args) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
JsonObject argObj = JsonUtil.fromJson(args, JsonObject.class);
|
||||
String elementID = argObj.get("elementID") == null ? null : argObj.get("elementID").getAsString();
|
||||
boolean includeElementData =
|
||||
argObj.get("includeElementData") != null &&
|
||||
argObj.get("includeElementData").getAsString().equals("true");
|
||||
try {
|
||||
msg = doaClient.retrieve(doi, elementID, includeElementData);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String call(String doi, String action, String args) {
|
||||
initClient();
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.call(doi, action, args.getBytes());
|
||||
return msg.body.getDataAsJsonString();
|
||||
} catch (IrpClientException e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public static String create(String repoID, String doString) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
DigitalObject dObj = DoipGson.getDoipGson().fromJson(doString, DigitalObject.class);
|
||||
for (Element e : dObj.elements) {
|
||||
if (null != e.dataString) {
|
||||
e.setData(e.dataString.getBytes());
|
||||
}
|
||||
e.dataString = null;
|
||||
}
|
||||
try {
|
||||
msg = doaClient.create(repoID, dObj);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String delete(String doID, String repoID) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.delete(doID, repoID);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String listOperation(String doID) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.listOperations(doID);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static String create(String repoID, ScriptObjectMirror doStr){
|
||||
// logger.debug(JsonUtil.toJson(doStr));
|
||||
// SM2KeyPair kp = JavaScriptEntry.getKeyPair();
|
||||
// HandleServiceUtils.CustomizeHandleService(kp,JavaScriptEntry.doi,HandleServiceUtils.LHS_Address);
|
||||
// DOAClient client = DOAClient.getGlobalInstance();
|
||||
// logger.debug(JsonUtil.toJson(doStr));
|
||||
// DigitalObject digitalObject = new DigitalObject(
|
||||
// doStr.get("doID").toString(),
|
||||
// DoType.DoString
|
||||
// );
|
||||
// digitalObject.addAttribute("content", doStr.get("doBody").toString());
|
||||
// try {
|
||||
// return new String(client.create(repoID,digitalObject).parameters.toByteArray());
|
||||
// }catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// return e.getMessage();
|
||||
// }
|
||||
// }
|
||||
|
||||
// public static String update(ScriptObjectMirror doStr){
|
||||
// SM2KeyPair kp = JavaScriptEntry.getKeyPair();
|
||||
// HandleServiceUtils.CustomizeHandleService(kp,JavaScriptEntry.doi,HandleServiceUtils.LHS_Address);
|
||||
// DOAClient client = DOAClient.getGlobalInstance();
|
||||
// DigitalObject digitalObject = new DigitalObject(
|
||||
// doStr.get("doID").toString(),
|
||||
// DoType.DoString
|
||||
// );
|
||||
// digitalObject.addAttribute("content", doStr.get("doBody").toString());
|
||||
// try {
|
||||
// return new String(client.update(digitalObject).parameters.toByteArray());
|
||||
// }catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// return e.getMessage();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
public static void initClient() {
|
||||
if (null == doaClient) {
|
||||
doaClient = ContractDOAClient.getContractDOAClientForTest();
|
||||
}
|
||||
}
|
||||
}
|
10
src/main/java/org/bdware/sc/boundry/utils/DOMUtil.java
Normal file
10
src/main/java/org/bdware/sc/boundry/utils/DOMUtil.java
Normal file
@ -0,0 +1,10 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
public class DOMUtil {
|
||||
public static Document parse(String html) {
|
||||
return Jsoup.parse(html);
|
||||
}
|
||||
}
|
42
src/main/java/org/bdware/sc/boundry/utils/FileUtil.java
Normal file
42
src/main/java/org/bdware/sc/boundry/utils/FileUtil.java
Normal file
@ -0,0 +1,42 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
|
||||
@PermissionStub(permission = Permission.File)
|
||||
public class FileUtil extends org.bdware.sc.util.FileUtil {
|
||||
private static String getInternalFile(String path) {
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
if (path.contains("..")) {
|
||||
return null;
|
||||
}
|
||||
File f = new File(parent, path);
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
|
||||
public static String getContent(String path) {
|
||||
return getFileContent(getInternalFile(path));
|
||||
}
|
||||
|
||||
public static void copyTo(String src, String dst) {
|
||||
try {
|
||||
String from = getInternalFile(src);
|
||||
String to = getInternalFile(dst);
|
||||
if (null == from || null == to) {
|
||||
throw new ScriptException("incorrect file name of from /to");
|
||||
}
|
||||
copyFile(from, to);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static PrintStream openAsPrinter(String path, boolean isAppend) {
|
||||
return openFileAsPrinter(getInternalFile(path), isAppend);
|
||||
}
|
||||
}
|
11
src/main/java/org/bdware/sc/boundry/utils/FileUtilStub.java
Normal file
11
src/main/java/org/bdware/sc/boundry/utils/FileUtilStub.java
Normal file
@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class FileUtilStub {
|
||||
|
||||
public static String getDir(String fullFileName) throws ScriptException {
|
||||
throw new ScriptException("Do not have File Permission");
|
||||
}
|
||||
|
||||
}
|
307
src/main/java/org/bdware/sc/boundry/utils/HttpUtil.java
Normal file
307
src/main/java/org/bdware/sc/boundry/utils/HttpUtil.java
Normal file
@ -0,0 +1,307 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import okhttp3.*;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.http.ApiGate;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@PermissionStub(permission = Permission.Http)
|
||||
public class HttpUtil {
|
||||
public static NashornScriptEngine currentEngine;
|
||||
|
||||
public static ScriptObject request(ScriptObjectMirror str) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
URL url = new URL((String) str.get("url"));
|
||||
String method = (String) str.get("method");
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setDoOutput(true);
|
||||
connection.setDoInput(true);
|
||||
connection.setUseCaches(false);
|
||||
connection.setInstanceFollowRedirects(true);
|
||||
connection.setRequestMethod(method.toUpperCase());
|
||||
Object headers = str.get("headers");
|
||||
if (headers != null && headers instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) headers;
|
||||
for (String key : som.getOwnKeys(true)) {
|
||||
Object val = som.get(key);
|
||||
if (val instanceof String) connection.setRequestProperty(key, (String) val);
|
||||
}
|
||||
} else {
|
||||
connection.setRequestProperty("Accept", "application/json");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
}
|
||||
connection.connect();
|
||||
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
|
||||
if (str.get("data") != null)
|
||||
out.append((String) str.get("data"));
|
||||
out.flush();
|
||||
out.close();
|
||||
ret.put("responseCode", connection.getResponseCode(), false);
|
||||
InputStream input = connection.getInputStream();
|
||||
Scanner sc = new Scanner(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (; sc.hasNextLine(); ) {
|
||||
sb.append(sc.nextLine()).append("\n");
|
||||
}
|
||||
sc.close();
|
||||
ret.put("response", sb.toString(), false);
|
||||
} catch (Throwable e) {
|
||||
ret.put("responseCode", 505, false);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("response", bo.toString(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public static String encodeURI(String str){
|
||||
return URLEncoder.encode(str);
|
||||
}
|
||||
public static String decodeURI(String str){
|
||||
return URLDecoder.decode(str);
|
||||
}
|
||||
|
||||
public static ScriptObject get(String str) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
URL url = new URL(str);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
ret.put("responseCode", connection.getResponseCode(), false);
|
||||
InputStream input = connection.getInputStream();
|
||||
Scanner sc = new Scanner(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (sc.hasNextLine()) {
|
||||
sb.append(sc.nextLine()).append("\n");
|
||||
}
|
||||
sc.close();
|
||||
ret.put("response", sb.toString(), false);
|
||||
} catch (Throwable e) {
|
||||
ret.put("resposeCode", 505, false);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("response", bo.toString(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ScriptObject post(ScriptObjectMirror str) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
URL url = new URL((String) str.get("url"));
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setDoOutput(true);
|
||||
connection.setDoInput(true);
|
||||
connection.setUseCaches(false);
|
||||
connection.setInstanceFollowRedirects(true);
|
||||
connection.setRequestMethod("POST");
|
||||
Object headers = str.get("headers");
|
||||
if (headers instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) headers;
|
||||
for (String key : som.getOwnKeys(true)) {
|
||||
Object val = som.get(key);
|
||||
if (val instanceof String) {
|
||||
connection.setRequestProperty(key, (String) val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
connection.setRequestProperty("Accept", "application/json");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
}
|
||||
connection.connect();
|
||||
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);
|
||||
out.append((String) str.get("data"));
|
||||
out.flush();
|
||||
out.close();
|
||||
ret.put("responseCode", connection.getResponseCode(), false);
|
||||
InputStream input = connection.getInputStream();
|
||||
Scanner sc = new Scanner(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (sc.hasNextLine()) {
|
||||
sb.append(sc.nextLine()).append("\n");
|
||||
}
|
||||
sc.close();
|
||||
ret.put("response", sb.toString(), false);
|
||||
} catch (Throwable e) {
|
||||
ret.put("responseCode", 505, false);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("response", bo.toString(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static CloseableHttpClient getHttpClient(String url) {
|
||||
try {
|
||||
SSLContext sslcontext =
|
||||
SSLContexts.custom()
|
||||
.loadTrustMaterial(
|
||||
null,
|
||||
(arg0, arg1) -> true)
|
||||
.build();
|
||||
|
||||
SSLConnectionSocketFactory sslSf =
|
||||
new SSLConnectionSocketFactory(
|
||||
sslcontext, null, null, new NoopHostnameVerifier());
|
||||
int tle = 10;
|
||||
if (url.contains("data.tj.gov.cn")) {
|
||||
tle = 3;
|
||||
}
|
||||
return HttpClients.custom()
|
||||
.setSSLSocketFactory(sslSf)
|
||||
.setKeepAliveStrategy((arg0, arg1) -> 0)
|
||||
.setConnectionTimeToLive(tle, TimeUnit.SECONDS)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// public static String httpPost(String str) {
|
||||
// System.out.println("JavaSScriptEntry httpPost:" + str);
|
||||
// PostRequest req = new PostRequest();
|
||||
// req = JsonUtil.fromJson(str, PostRequest.class);
|
||||
// // System.out.println("url========>" + req.url);
|
||||
// // System.out.println("data=======>" + req.data);
|
||||
//
|
||||
// Result r = new Result();
|
||||
// try {
|
||||
// URL url = new URL(req.url);//
|
||||
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
// connection.setDoOutput(true);
|
||||
// connection.setDoInput(true);
|
||||
// connection.setUseCaches(false);
|
||||
// connection.setInstanceFollowRedirects(true);
|
||||
// connection.setRequestMethod("POST");
|
||||
// connection.setRequestProperty("Accept", "application/json");
|
||||
// connection.setRequestProperty("Content-Type", "application/json");
|
||||
// connection.connect();
|
||||
// OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); //
|
||||
// utf-8缂栫爜
|
||||
// out.append(req.data);
|
||||
// out.flush();
|
||||
// out.close();
|
||||
//
|
||||
// r.resposeCode = connection.getResponseCode();
|
||||
// InputStream input = connection.getInputStream();
|
||||
//
|
||||
// Scanner sc = new Scanner(input);
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (; sc.hasNextLine();) {
|
||||
// sb.append(sc.nextLine()).append("\n");
|
||||
// }
|
||||
// sc.close();
|
||||
// r.response = sb.toString();
|
||||
// return JsonUtil.toJson(r);
|
||||
// } catch (Throwable e) {
|
||||
// r.resposeCode = 505;
|
||||
// // ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// // e.printStackTrace(new PrintStream(bo));
|
||||
// r.response = e.getMessage();
|
||||
// return JsonUtil.toJson(r);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static String postTask(String args, final ScriptFunction callback) {
|
||||
System.out.println("[JavaScriptEntry]" + args);
|
||||
PostRequest req = new PostRequest();
|
||||
req = JsonUtil.fromJson(args, PostRequest.class);
|
||||
|
||||
OkHttpClient okHttpClient = new OkHttpClient(); //
|
||||
RequestBody body =
|
||||
RequestBody.create(MediaType.parse("application/json; charset=utf-8"), req.data);
|
||||
Request request = new Request.Builder().url(req.url).post(body).build(); // 2.瀹氫箟涓<EFBFBD>涓猺equest
|
||||
Call call = okHttpClient.newCall(request); //
|
||||
call.enqueue(
|
||||
new Callback() { //
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
String result = response.body().string(); //
|
||||
System.out.println("currentEngine:");
|
||||
DesktopEngine.applyWithGlobal(
|
||||
callback, currentEngine.getNashornGlobal(), result);
|
||||
}
|
||||
});
|
||||
return "success";
|
||||
}
|
||||
|
||||
// public static String httpGet(String str) {
|
||||
// // System.out.println("JavaScriptEntry httpGet:" + str);
|
||||
// Result r = new Result();
|
||||
// try {
|
||||
// HttpGet httpGet = new HttpGet(str);
|
||||
// RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(60000)
|
||||
// .setConnectTimeout(60000).setSocketTimeout(60000).build();
|
||||
// httpGet.setConfig(requestConfig);
|
||||
// httpGet.addHeader("Pragma", "no-cache");
|
||||
// httpGet.addHeader("Cache-Control", "no-cache");
|
||||
// httpGet.addHeader("Upgrade-Insecure-Requests", "1");
|
||||
// httpGet.addHeader("User-Agent",
|
||||
// "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko)
|
||||
// Chrome/78.0.3904.97 Safari/537.36");
|
||||
// httpGet.addHeader("Sec-Fetch-User", "?1");
|
||||
// httpGet.addHeader("Accept",
|
||||
//
|
||||
// "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
|
||||
// httpGet.addHeader("Sec-Fetch-Site", "none");
|
||||
// httpGet.addHeader("Sec-Fetch-Mode", "navigate");
|
||||
// httpGet.addHeader("Accept-Encoding", "gzip, deflate, br");
|
||||
// httpGet.addHeader("Accept-Language", "zh-CN,zh;q=0.9");
|
||||
// CloseableHttpResponse response1 = getHttpClient(str).execute(httpGet);
|
||||
// InputStream content = response1.getEntity().getContent();
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// byte[] buff = new byte[4096];
|
||||
// for (int k = 0; (k = content.read(buff)) > 0;) {
|
||||
// bo.write(buff, 0, k);
|
||||
// }
|
||||
// r.response = bo.toString();
|
||||
// return JsonUtil.toJson(r);
|
||||
// } catch (Throwable e) {
|
||||
// r.resposeCode = 505;
|
||||
// // ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// // e.printStackTrace(new PrintStream(bo));
|
||||
// r.response = e.getMessage();
|
||||
// return JsonUtil.toJson(r);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static ApiGate createAPIGate(String ip) {
|
||||
return new ApiGate(ip);
|
||||
}
|
||||
|
||||
public static ApiGate createAPIGate(String ip, String port) {
|
||||
return new ApiGate(ip, Integer.parseInt(port));
|
||||
}
|
||||
|
||||
static class PostRequest {
|
||||
String url;
|
||||
String data;
|
||||
}
|
||||
}
|
54
src/main/java/org/bdware/sc/boundry/utils/LedgerUtil.java
Normal file
54
src/main/java/org/bdware/sc/boundry/utils/LedgerUtil.java
Normal file
@ -0,0 +1,54 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.bdledger.api.grpc.Client;
|
||||
import org.bdware.bdledger.api.grpc.pb.CommonProto.Transaction;
|
||||
import org.bdware.bdledger.api.grpc.pb.CommonProto.TransactionType;
|
||||
import org.bdware.bdledger.api.grpc.pb.LedgerProto.SendTransactionResponse;
|
||||
import org.bdware.bdledger.api.grpc.pb.QueryProto.GetTransactionByHashResponse;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
@PermissionStub(permission = Permission.Ledger)
|
||||
public class LedgerUtil {
|
||||
static SecureRandom random = new SecureRandom((System.currentTimeMillis() + "").getBytes());
|
||||
|
||||
public static Client getClient(ScriptObjectMirror str) {
|
||||
return new Client((String) str.get("ip"), Integer.parseInt(str.get("port").toString()));
|
||||
}
|
||||
|
||||
public static ScriptObject queryByHash(Client c, ScriptObjectMirror str) {
|
||||
String ledger = str.get("ledger").toString();
|
||||
String hash = str.get("hash").toString();
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
GetTransactionByHashResponse result = c.getTransactionByHashSync(ledger, hash);
|
||||
Transaction transaction = result.getTransaction();
|
||||
ret.put("from", HashUtil.byteArray2Str(transaction.getFrom().toByteArray(), 0), false);
|
||||
ret.put("to", HashUtil.byteArray2Str(transaction.getTo().toByteArray(), 0), false);
|
||||
ret.put("type", transaction.getType().toString(), false);
|
||||
ret.put("data", new String(transaction.getData().toByteArray()), false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String sendTransaction(Client c, ScriptObjectMirror str) {
|
||||
String ledger = str.get("ledger").toString();
|
||||
String from = str.get("from").toString();
|
||||
String to = str.get("to").toString();
|
||||
String data = str.get("data").toString();
|
||||
SendTransactionResponse result =
|
||||
c.sendTransactionSync(
|
||||
ledger,
|
||||
TransactionType.MESSAGE,
|
||||
from,
|
||||
random.nextLong(),
|
||||
to,
|
||||
data.getBytes());
|
||||
return HashUtil.byteArray2Str(result.getHash().toByteArray(), 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
@PermissionStub(permission = Permission.MongoDB)
|
||||
public class MongoDBUtil extends org.bdware.sc.blockdb.MongoDBUtil {
|
||||
}
|
19
src/main/java/org/bdware/sc/boundry/utils/README.md
Normal file
19
src/main/java/org/bdware/sc/boundry/utils/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# 简介
|
||||
|
||||
这个包里对yjs层提供了XXUtil功能的调用。 要添加一个Util需要以下步骤。
|
||||
|
||||
## 1.新增加一个带@PermissionStub的注解
|
||||
|
||||
注意注解里的Permission要和类名一致。
|
||||
|
||||
```java
|
||||
|
||||
@PermissionStub(permission = "ABC")
|
||||
public class ABCUtil {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 2.在org.bdware.sc.node.Permission中添加这个权限
|
||||
|
||||
## 3.在doc项目的@Permission注解说明里
|
105
src/main/java/org/bdware/sc/boundry/utils/RocksDBUtil.java
Normal file
105
src/main/java/org/bdware/sc/boundry/utils/RocksDBUtil.java
Normal file
@ -0,0 +1,105 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.rocksdb.Options;
|
||||
import org.rocksdb.RocksDB;
|
||||
import org.rocksdb.RocksDBException;
|
||||
import org.rocksdb.RocksIterator;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@PermissionStub(permission = Permission.RocksDB)
|
||||
public class RocksDBUtil {
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
RocksDB rocksDB;
|
||||
|
||||
public RocksDBUtil(String path, boolean readOnly) {
|
||||
try {
|
||||
Options options = new Options();
|
||||
options.setCreateIfMissing(true);
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
path = new File(parent, path).getAbsolutePath();
|
||||
File lockFile = new File(path, "LOCK");
|
||||
lockFile.delete();
|
||||
if (readOnly) {
|
||||
rocksDB = RocksDB.openReadOnly(options, path);
|
||||
} else rocksDB = RocksDB.open(options, path);
|
||||
} catch (RocksDBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static RocksDBUtil loadDB(String path, boolean readOnly) {
|
||||
return new RocksDBUtil(path, readOnly);
|
||||
}
|
||||
|
||||
public static RocksDBUtil loadDB(String path, String readOnly) {
|
||||
return new RocksDBUtil(path, Boolean.parseBoolean(readOnly));
|
||||
}
|
||||
|
||||
public String get(String key) {
|
||||
try {
|
||||
return new String(rocksDB.get(key.getBytes()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public long estimateKeySize() {
|
||||
try {
|
||||
return rocksDB.getLongProperty("rocksdb.estimate-num-keys");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String key, String value) {
|
||||
try {
|
||||
rocksDB.put(key.getBytes(), value.getBytes());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String delete(String key) {
|
||||
try {
|
||||
rocksDB.delete(key.getBytes());
|
||||
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "failed";
|
||||
}
|
||||
|
||||
public RocksIterator newIterator() {
|
||||
try {
|
||||
return rocksDB.newIterator();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ScriptObject getNext(RocksIterator iter) {
|
||||
|
||||
if (iter.isValid()) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
ret.put("key", new String(iter.key()), false);
|
||||
ret.put("value", new String(iter.value()), false);
|
||||
iter.next();
|
||||
return ret;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
93
src/main/java/org/bdware/sc/boundry/utils/SM2Util.java
Normal file
93
src/main/java/org/bdware/sc/boundry/utils/SM2Util.java
Normal file
@ -0,0 +1,93 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
|
||||
import org.zz.gmhelper.BCECUtil;
|
||||
import org.zz.gmhelper.SM2KeyPair;
|
||||
import org.zz.gmhelper.SM3Util;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@PermissionStub(permission = Permission.SM2)
|
||||
public class SM2Util {
|
||||
|
||||
public static ScriptObject generateKeyPair() {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
SM2KeyPair keyPair = org.zz.gmhelper.SM2Util.generateSM2KeyPair();
|
||||
ret.put("publicKey", keyPair.getPublicKeyStr(), false);
|
||||
ret.put("privateKey", keyPair.getPrivateKeyStr(), false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ScriptObject sign(String content, ScriptObjectMirror keyPair) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
BigInteger privateKey = new BigInteger(keyPair.getMember("privateKey").toString(), 16);
|
||||
ECPrivateKeyParameters priKey =
|
||||
new ECPrivateKeyParameters(privateKey, org.zz.gmhelper.SM2Util.DOMAIN_PARAMS);
|
||||
byte[] sign = org.zz.gmhelper.SM2Util.sign(priKey, content.getBytes());
|
||||
sign = org.zz.gmhelper.SM2Util.decodeDERSM2Sign(sign);
|
||||
ret.put("status", "success", false);
|
||||
ret.put("signature", ByteUtils.toHexString(sign), false);
|
||||
} catch (Exception e) {
|
||||
ret.put("status", "failed", false);
|
||||
ret.put("message", "invalid keyPair", false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ScriptObject verify(String content, String signature, String pubKeyStr) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
byte[] sig = ByteUtils.fromHexString(signature);
|
||||
sig = org.zz.gmhelper.SM2Util.encodeSM2SignToDER(sig);
|
||||
ECPublicKeyParameters pubKey =
|
||||
BCECUtil.createECPublicKeyFromStrParameters(
|
||||
pubKeyStr,
|
||||
org.zz.gmhelper.SM2Util.CURVE,
|
||||
org.zz.gmhelper.SM2Util.DOMAIN_PARAMS);
|
||||
boolean value = org.zz.gmhelper.SM2Util.verify(pubKey, content.getBytes(), sig);
|
||||
if (value) ret.put("status", "success", false);
|
||||
else ret.put("status", "failed", false);
|
||||
ret.put("result", value, false);
|
||||
} catch (Exception e) {
|
||||
ret.put("status", "failed", false);
|
||||
ret.put("result", "invalid keyPair or signature ", false);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String encrypt(String content, String pubkey) {
|
||||
try {
|
||||
return ByteUtils.toHexString(
|
||||
org.zz.gmhelper.SM2Util.encrypt(
|
||||
SM2KeyPair.publicKeyStr2ECPoint(pubkey), content.getBytes()));
|
||||
} catch (InvalidCipherTextException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String decrypt(String content, String privateKey) {
|
||||
try {
|
||||
ECPrivateKeyParameters privateKeyParam =
|
||||
new ECPrivateKeyParameters(
|
||||
new BigInteger(privateKey, 16), org.zz.gmhelper.SM2Util.DOMAIN_PARAMS);
|
||||
return new String(
|
||||
org.zz.gmhelper.SM2Util.decrypt(
|
||||
privateKeyParam, ByteUtils.fromHexString(content)));
|
||||
} catch (InvalidCipherTextException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
62
src/main/java/org/bdware/sc/boundry/utils/SQLUtil.java
Normal file
62
src/main/java/org/bdware/sc/boundry/utils/SQLUtil.java
Normal file
@ -0,0 +1,62 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.util.Properties;
|
||||
|
||||
@PermissionStub(permission = Permission.SQL)
|
||||
public class SQLUtil {
|
||||
public static void initDriver(String driver) {
|
||||
try {
|
||||
Thread.currentThread()
|
||||
.setContextClassLoader(ContractProcess.instance.engine.getClassLoad());
|
||||
Class.forName(driver, true, ContractProcess.instance.engine.getClassLoad());
|
||||
} catch (Exception e) {
|
||||
System.out.println(
|
||||
"Still can't find class! Cl of SQLUtil:\n\t\t"
|
||||
+ SQLUtil.class.getClassLoader());
|
||||
System.out.println(
|
||||
"Cl of DEgine:\n\t\t" + ContractProcess.instance.engine.getClassLoad());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Connection getConnection(String url, String user, String password) {
|
||||
try {
|
||||
Thread.currentThread()
|
||||
.setContextClassLoader(ContractProcess.instance.engine.getClassLoad());
|
||||
if (!url.startsWith("jdbc")) {
|
||||
url += "jdbc:mysql://";
|
||||
}
|
||||
java.util.Properties info = new java.util.Properties();
|
||||
|
||||
if (user != null && !"undefined".equals(user)) {
|
||||
info.put("user", user);
|
||||
}
|
||||
if (password != null && !"undefined".equals(password)) {
|
||||
info.put("password", password);
|
||||
}
|
||||
if (url.startsWith("jdbc:postgresql")) info.put("sslmode", "allow");
|
||||
|
||||
Class<?> clz =
|
||||
Class.forName(
|
||||
"java.sql.DriverManager",
|
||||
true,
|
||||
ContractProcess.instance.engine.getClassLoad());
|
||||
// set caller class into null, thus use YJSClassLoader in
|
||||
// DriverManager.isDriverAllowed(driver,classloader);
|
||||
Method m =
|
||||
clz.getDeclaredMethod(
|
||||
"getConnection", String.class, Properties.class, Class.class);
|
||||
m.setAccessible(true);
|
||||
return (Connection) m.invoke(null, url, info, null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
59
src/main/java/org/bdware/sc/boundry/utils/UtilRegistry.java
Normal file
59
src/main/java/org/bdware/sc/boundry/utils/UtilRegistry.java
Normal file
@ -0,0 +1,59 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.compiler.PermissionStubGenerator;
|
||||
import org.bdware.sc.engine.YJSClassLoader;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class UtilRegistry {
|
||||
private static final Logger LOGGER = LogManager.getLogger(UtilRegistry.class);
|
||||
public static Map<String, String> stubClzNameMap = new HashMap<>();
|
||||
|
||||
public static List<Class<?>> getUtilClasses() {
|
||||
List<String> allName = Permission.allName();
|
||||
List<Class<?>> ret = new ArrayList<>();
|
||||
for (String name : allName) {
|
||||
Class<?> clz;
|
||||
try {
|
||||
clz = Class.forName(String.format("%s.%sUtil", UtilRegistry.class.getPackage().getName(), name));
|
||||
ret.add(clz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void defineUtilClass(YJSClassLoader classLoader) {
|
||||
List<Class<?>> clzs = UtilRegistry.getUtilClasses();
|
||||
for (Class<?> aClass : clzs) {
|
||||
PermissionStub stub = aClass.getAnnotation(PermissionStub.class);
|
||||
if (stub == null) {
|
||||
continue;
|
||||
}
|
||||
byte[] stubClz = PermissionStubGenerator.generateStub(aClass, stub.permission().name());
|
||||
String stubClzName = aClass.getCanonicalName() + "Stub";
|
||||
stubClzNameMap.put(stub.permission().name(), stubClzName);
|
||||
classLoader.defineStubClass(stubClzName, stubClz);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getInitStr(String s, boolean open) {
|
||||
if (stubClzNameMap.containsKey(s)) {
|
||||
String ret =
|
||||
String.format(
|
||||
"%sUtil = %s.%sUtil%s;\n",
|
||||
s, UtilRegistry.class.getPackage().getName(), s, open ? "" : "Stub");
|
||||
LOGGER.debug(ret);
|
||||
return ret;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.bdware.sc.compiler;
|
||||
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public abstract class AnnotationProcessor {
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
return;
|
||||
}
|
||||
}
|
224
src/main/java/org/bdware/sc/compiler/YJSCompiler.java
Normal file
224
src/main/java/org/bdware/sc/compiler/YJSCompiler.java
Normal file
@ -0,0 +1,224 @@
|
||||
package org.bdware.sc.compiler;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.DiagnosticErrorListener;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.engine.YJSFilter;
|
||||
import org.bdware.sc.node.*;
|
||||
import org.bdware.sc.parser.JavaScriptLexer;
|
||||
import org.bdware.sc.parser.YJSParser;
|
||||
import org.bdware.sc.parser.YJSParser.ProgramContext;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.bdware.sc.visitor.ContractReader;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.Context;
|
||||
import wrp.jdk.nashorn.internal.runtime.ErrorManager;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import wrp.jdk.nashorn.internal.runtime.Source;
|
||||
import wrp.jdk.nashorn.internal.runtime.options.Options;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class YJSCompiler {
|
||||
public boolean withProgramPointCount;
|
||||
YJSErrorListener errorListener = new YJSErrorListener();
|
||||
ContractNode contract;
|
||||
private static final Logger LOGGER = LogManager.getLogger(YJSCompiler.class);
|
||||
|
||||
public YJSCompiler() {
|
||||
}
|
||||
|
||||
public static ScriptFunction compileWithGlobal(Source source, Global global, Context context) {
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != global);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
return context.compileScript(source).getFunction(global);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Context makeContext(
|
||||
final InputStream in, final OutputStream out, final OutputStream err) {
|
||||
final PrintStream pout =
|
||||
out instanceof PrintStream ? (PrintStream) out : new PrintStream(out);
|
||||
final PrintStream perr =
|
||||
err instanceof PrintStream ? (PrintStream) err : new PrintStream(err);
|
||||
final PrintWriter wout = new PrintWriter(pout, true);
|
||||
final PrintWriter werr = new PrintWriter(perr, true);
|
||||
|
||||
// Set up error handler.
|
||||
final ErrorManager errors = new ErrorManager(werr);
|
||||
// Set up options.
|
||||
final Options options = new Options("nashorn", werr);
|
||||
options.process(new String[] {});
|
||||
// detect scripting mode by any source's first character being '#'
|
||||
options.set("persistent.code.cache", true);
|
||||
options.set("print.code", "true");
|
||||
options.set("print.parse", true);
|
||||
|
||||
if (!options.getBoolean("scripting")) {
|
||||
for (final String fileName : options.getFiles()) {
|
||||
final File firstFile = new File(fileName);
|
||||
if (firstFile.isFile()) {
|
||||
try (final FileReader fr = new FileReader(firstFile)) {
|
||||
final int firstChar = fr.read();
|
||||
// starts with '#
|
||||
if (firstChar == '#') {
|
||||
options.set("scripting", true);
|
||||
break;
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
// ignore this. File IO errors will be reported later
|
||||
// anyway
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Context(
|
||||
options,
|
||||
errors,
|
||||
wout,
|
||||
werr,
|
||||
Thread.currentThread().getContextClassLoader(),
|
||||
new YJSFilter(),
|
||||
null);
|
||||
}
|
||||
|
||||
public ContractZipBundle compile(ZipFile zf) throws Exception {
|
||||
ContractZipBundle czb = new ContractZipBundle();
|
||||
ZipEntry manifest = zf.getEntry("/manifest.json");
|
||||
if (null == manifest) {
|
||||
throw new IllegalStateException("manifest.json is not exists!");
|
||||
}
|
||||
InputStream manifestInput = zf.getInputStream(manifest);
|
||||
// Gson gson = new GsonBuilder().registerTypeAdapter(Contract.Type.class,
|
||||
// typeAdapter)
|
||||
|
||||
ContractManifest cm =
|
||||
JsonUtil.GSON.fromJson(
|
||||
new InputStreamReader(manifestInput), ContractManifest.class);
|
||||
|
||||
// 如果没有就不限制,根据gas进行插装
|
||||
if (0L != cm.getInsnLimit()) {
|
||||
System.out.println("++++++++++++++++++++++true");
|
||||
}
|
||||
czb.setManifest(cm);
|
||||
Set<String> toParse = new HashSet<>();
|
||||
toParse.add(cm.main);
|
||||
Set<String> todo = new HashSet<>();
|
||||
while (toParse.size() > 0) {
|
||||
for (String str : toParse) {
|
||||
if (czb.containsPath(str)) {
|
||||
continue;
|
||||
}
|
||||
ZipEntry entry = zf.getEntry("/" + str);
|
||||
if (null == entry) {
|
||||
throw new IllegalStateException("missing import:" + str);
|
||||
}
|
||||
ContractNode cn = compile(zf.getInputStream(entry), str);
|
||||
czb.put(str, cn);
|
||||
System.out.println("----" + str);
|
||||
for (ImportNode in : cn.getImports()) {
|
||||
todo.add(in.getPath());
|
||||
}
|
||||
}
|
||||
toParse.clear();
|
||||
for (String str : todo) {
|
||||
if (!czb.containsPath(str)) {
|
||||
toParse.add(str);
|
||||
}
|
||||
}
|
||||
todo.clear();
|
||||
}
|
||||
// add function _preSub
|
||||
// Kaidong Wu
|
||||
String preSubConName = cm.main.substring(0, cm.main.length() - 4) + "PreSub";
|
||||
String preSubContract =
|
||||
"contract "
|
||||
+ preSubConName
|
||||
+ " { function _preSub (e) { YancloudUtil.preSub(e.topic, e.content); }}";
|
||||
ContractNode preSubNode =
|
||||
compile(
|
||||
new ByteArrayInputStream(preSubContract.getBytes(StandardCharsets.UTF_8)),
|
||||
preSubConName + ".yjs");
|
||||
czb.put(preSubConName + ".yjs", preSubNode);
|
||||
LOGGER.info("--compile-- " + preSubConName);
|
||||
return czb;
|
||||
}
|
||||
|
||||
public ContractNode compile(InputStream input, String fileName) throws IOException {
|
||||
// 词法分析
|
||||
JavaScriptLexer lexer = new JavaScriptLexer(new ANTLRInputStream(input));
|
||||
lexer.setUseStrictDefault(true);
|
||||
CommonTokenStream cts = new CommonTokenStream(lexer);
|
||||
// 语法分析
|
||||
YJSParser parser = new YJSParser(cts);
|
||||
parser.removeErrorListeners();
|
||||
parser.addErrorListener(errorListener);
|
||||
parser.addErrorListener(new DiagnosticErrorListener());
|
||||
ProgramContext tree = parser.program();
|
||||
// 应该是antlr4访问器进行遍历语法树
|
||||
ContractReader reader = new ContractReader(fileName);
|
||||
System.out.println("遍历语法树");
|
||||
contract = reader.visitProgram(tree);
|
||||
// 遍历完 获取 contract 里的 yjs type
|
||||
System.out.println(contract.getYjsType());
|
||||
contract.initPlainText(cts);
|
||||
handleAnnotation(contract);//处理注解
|
||||
return contract;
|
||||
}
|
||||
|
||||
private void handleAnnotation(ContractNode contractNode) {
|
||||
System.out.println("handleAnnotation");
|
||||
for (AnnotationNode node : contract.annotations) {
|
||||
AnnotationProcessor processor = findProcessor(node);
|
||||
if (processor != null) {
|
||||
processor.processContract(node, contractNode);
|
||||
}
|
||||
}
|
||||
for (FunctionNode functionNode : contractNode.getFunctions()) {
|
||||
List<AnnotationNode> annos = functionNode.annotations;//函数里的annotation
|
||||
if (annos != null)
|
||||
for (AnnotationNode anno : annos) {
|
||||
System.out.println(anno.getType());//打印类型和参数
|
||||
System.out.println(anno.getArgs());
|
||||
AnnotationProcessor processor = findProcessor(anno);
|
||||
if (processor != null)
|
||||
processor.processFunction(anno, contractNode, functionNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationProcessor findProcessor(AnnotationNode node) {
|
||||
try {
|
||||
String clzName = YJSCompiler.class.getPackage().getName();
|
||||
clzName += ".ap." + node.getType();
|
||||
Class<?> clz = Class.forName(clzName);
|
||||
return (AnnotationProcessor) clz.getConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> syntaxError() {
|
||||
return errorListener.result;
|
||||
}
|
||||
}
|
15
src/main/java/org/bdware/sc/compiler/ap/Access.java
Normal file
15
src/main/java/org/bdware/sc/compiler/ap/Access.java
Normal file
@ -0,0 +1,15 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
|
||||
public class Access extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
contractNode.sigRequired = false;
|
||||
if (anno != null) {
|
||||
contractNode.sigRequired = "\"verified\"".equals(anno.getArgs().get(0));
|
||||
}
|
||||
}
|
||||
}
|
12
src/main/java/org/bdware/sc/compiler/ap/Confidential.java
Normal file
12
src/main/java/org/bdware/sc/compiler/ap/Confidential.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Confidential extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setConfidential(true); }
|
||||
}
|
19
src/main/java/org/bdware/sc/compiler/ap/Cost.java
Normal file
19
src/main/java/org/bdware/sc/compiler/ap/Cost.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.CostDetail;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
public class Cost extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
CostDetail detail = JsonUtil.fromJson(anno.getArgs().get(0), CostDetail.class);
|
||||
functionNode.setCost(detail);
|
||||
if (detail.isCountGas())
|
||||
contractNode.setInstrumentBranch(true);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class HomomorphicDecrypt extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setHomomorphicDecrypt(true);
|
||||
functionNode.setKeyManagerID(anno.getArgs().get(0));
|
||||
functionNode.setSecretID(anno.getArgs().get(1));
|
||||
functionNode.setHomoDecryptConf(JsonParser.parseString(anno.getArgs().get(2)));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class HomomorphicEncrypt extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setHomomorphicEncrypt(true);
|
||||
functionNode.setKeyManagerID(anno.getArgs().get(0));
|
||||
functionNode.setSecretID(anno.getArgs().get(1));
|
||||
functionNode.setHomoEncryptConf(JsonParser.parseString(anno.getArgs().get(2)));
|
||||
}
|
||||
}
|
17
src/main/java/org/bdware/sc/compiler/ap/Join.java
Normal file
17
src/main/java/org/bdware/sc/compiler/ap/Join.java
Normal file
@ -0,0 +1,17 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.bean.JoinInfo;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Join extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
// functionNode.setRouteInfo(RouteInfo.create(anno,contractNode));
|
||||
//增加标记,在ContractNode中记录Join相关的函数和Join规则
|
||||
functionNode.setJoinInfo(JoinInfo.create(anno,contractNode));
|
||||
}
|
||||
}
|
32
src/main/java/org/bdware/sc/compiler/ap/LogLocation.java
Normal file
32
src/main/java/org/bdware/sc/compiler/ap/LogLocation.java
Normal file
@ -0,0 +1,32 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class LogLocation extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
for (FunctionNode fn : contractNode.getFunctions()) {
|
||||
fn.addAnnotation(anno);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
if (anno != null && anno.getArgs() != null)
|
||||
for (String s : anno.getArgs()) {
|
||||
if (s.equals("\"dataware\"")
|
||||
|| s.equals("\"bdledger\"")
|
||||
|| s.equals("\"bdledger:\"")) {
|
||||
functionNode.setLogToBDContract(true);
|
||||
} else if (s.startsWith("\"bdledger:") && s.length() > 11) {
|
||||
functionNode.setLogToNamedLedger(true);
|
||||
String[] tmp = s.substring(1, s.length() - 1).split(":");
|
||||
functionNode.addLedgerName(tmp[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
src/main/java/org/bdware/sc/compiler/ap/LogType.java
Normal file
26
src/main/java/org/bdware/sc/compiler/ap/LogType.java
Normal file
@ -0,0 +1,26 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class LogType extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
contractNode.setLogType(anno.getArgs());
|
||||
for (FunctionNode fn : contractNode.getFunctions()) {
|
||||
fn.addAnnotation(anno);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
for (String str : anno.getArgs()) {
|
||||
org.bdware.sc.node.LogType type = org.bdware.sc.node.LogType.parse(str);
|
||||
functionNode.addLogType(type);
|
||||
if (type == org.bdware.sc.node.LogType.Branch) contractNode.setInstrumentBranch(true);
|
||||
}
|
||||
}
|
||||
}
|
6
src/main/java/org/bdware/sc/compiler/ap/Param.java
Normal file
6
src/main/java/org/bdware/sc/compiler/ap/Param.java
Normal file
@ -0,0 +1,6 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
|
||||
public class Param extends AnnotationProcessor {
|
||||
}
|
12
src/main/java/org/bdware/sc/compiler/ap/Permission.java
Normal file
12
src/main/java/org/bdware/sc/compiler/ap/Permission.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
|
||||
public class Permission extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
contractNode.setPermission(anno.getArgs());
|
||||
}
|
||||
}
|
17
src/main/java/org/bdware/sc/compiler/ap/Route.java
Normal file
17
src/main/java/org/bdware/sc/compiler/ap/Route.java
Normal file
@ -0,0 +1,17 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.bdware.sc.bean.RouteInfo;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.CostDetail;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Route extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setRouteInfo(RouteInfo.create(anno,contractNode));
|
||||
}
|
||||
}
|
16
src/main/java/org/bdware/sc/compiler/ap/Split.java
Normal file
16
src/main/java/org/bdware/sc/compiler/ap/Split.java
Normal file
@ -0,0 +1,16 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.bean.RouteInfo;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Split extends AnnotationProcessor {
|
||||
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setRouteInfo(RouteInfo.create(anno,contractNode));
|
||||
}
|
||||
}
|
323
src/main/java/org/bdware/sc/engine/ConfidentialContractUtil.java
Normal file
323
src/main/java/org/bdware/sc/engine/ConfidentialContractUtil.java
Normal file
@ -0,0 +1,323 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptException;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class ConfidentialContractUtil {
|
||||
|
||||
public static final String CONFIDENTIAL_TEMPLATE_PATH = System.getenv("GRAPHENE_DIR")
|
||||
+ File.separator + "Examples" + File.separator + "nodejs-secret";
|
||||
public static final String CONFIDENTIAL_SCRIPT_PATH = System.getenv("GRAPHENE_DIR")
|
||||
+ File.separator + "App";
|
||||
public static final String[] COMMAND = {"bash", "executeContract.sh"};
|
||||
private static final Type MapType = TypeToken.getParameterized(HashMap.class, String.class, String.class).getType();
|
||||
|
||||
public static String executeConfidentialContract(ContractRequest input) throws IOException, InterruptedException {
|
||||
File runDir = new File(CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID());
|
||||
ProcessBuilder pb = new ProcessBuilder(COMMAND);
|
||||
pb.directory(runDir);
|
||||
Process p = pb.start();
|
||||
p.waitFor();
|
||||
File resultFile = new File(CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID() +
|
||||
File.separator + "result.json");
|
||||
return FileUtils.readFileToString(resultFile, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static void generateConfidentialContract(ContractNode cn, ScriptObjectMirror globalVars, Global global) {
|
||||
List<FunctionNode> functionNodes = cn.getFunctions();
|
||||
for (FunctionNode fn : functionNodes) {
|
||||
// assuming only one confidential function for now
|
||||
if (fn.isConfidential()) {
|
||||
StringBuilder jsStr = new StringBuilder();
|
||||
// find all dependent functions
|
||||
Set<String> dependentFunctions = findAllDependentFunctions(cn, fn);
|
||||
// add self and all dependent function declaration
|
||||
for (FunctionNode fNode : functionNodes) {
|
||||
if (dependentFunctions.contains(fNode.functionName)) {
|
||||
jsStr.append(fNode.plainText()).append("\n");
|
||||
}
|
||||
}
|
||||
// load necessary Node.js libraries
|
||||
jsStr.append("var fs = require('fs');\n" + "var crypto = require('crypto');\n" + "var sm2 = require('sm-crypto').sm2;\n");
|
||||
// load Global variables and arguments from files
|
||||
jsStr.append("let rawGlobal = fs.readFileSync('global.json').toString();\n" + "let Global = JSON.parse(rawGlobal);\n");
|
||||
jsStr.append("let rawArg = fs.readFileSync('arg.json').toString();\n" + "let jsonArg = JSON.parse(rawArg);\n" + "let requester = jsonArg.requester;\n" + "let arg = jsonArg.arg;\n");
|
||||
jsStr.append("let srcStr = fs.readFileSync('contract.js').toString();\n");
|
||||
// verify signatures and decrypt all confidential variables Important!!!!!
|
||||
jsStr.append("for (var k in Global) {\n" + " if (Global.hasOwnProperty(k)) {\n" + " if (k.startsWith('conf_')) {\n" + " let sig = Global[k].signature;\n" + " let pubKey = Global[k].owner;\n" + " let verifyResult = sm2.doVerifySignature(srcStr, sig, pubKey);\n" + " if (verifyResult) {\n" + " let newKey = k.substring(5);\n" + " let decKey = Buffer.from(process.env['KEY_'+pubKey.substring(0,10).toUpperCase()], 'hex');\n" + " let decIv = Buffer.from(Global[k].iv, 'hex');\n" + " let cipherText = Buffer.from(Global[k].cipherText, 'hex');\n" + " let decipher = crypto.createDecipheriv('aes-256-cbc', decKey, decIv);\n" + " let decrypted = decipher.update(cipherText);\n" + " decrypted = Buffer.concat([decrypted, decipher.final()]);\n" + " let plaintext = decrypted.toString();\n" + " Global[newKey] = plaintext;\n" + " }\n" + " }\n" + " }\n" + "}\n");
|
||||
// call function
|
||||
jsStr.append("var ret = ").append(fn.functionName).append("(arg, requester, null);\n");
|
||||
// TODO: encrypt all confidential variables so state can be updated in confidential function @shujunyi
|
||||
// encrypt return value and write to a file
|
||||
jsStr.append("var retStr = JSON.stringify(ret);\n" + "var key = Buffer.from(process.env['KEY_'+requester.substring(0,10).toUpperCase()], 'hex');\n" + "var iv = crypto.randomBytes(16);\n" + "let cipher = crypto.createCipheriv('aes-256-cbc', key, iv); \n" + "let encRet = cipher.update(retStr);\n" + "encRet = Buffer.concat([encRet, cipher.final()]);\n" + "let result = {iv: iv.toString('hex'), encryptedData: encRet.toString('hex')};\n" + "let resultStr = JSON.stringify(result);\n" + "fs.writeFileSync('result.json', resultStr);\n");
|
||||
// put script into Global so owner can send it and collect signatures
|
||||
Object som = ScriptObjectMirror.wrap(jsStr.toString(), global);
|
||||
globalVars.put("src_" + fn.functionName, som);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyTemplateToDestination(ContractRequest input) {
|
||||
String dest = CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID();
|
||||
File srcDir = new File(CONFIDENTIAL_TEMPLATE_PATH);
|
||||
File destDir = new File(dest);
|
||||
try {
|
||||
FileUtils.copyDirectory(srcDir, destDir);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void dumpScriptAndStates(
|
||||
Invocable engine,
|
||||
FunctionNode functionNode,
|
||||
ContractRequest input,
|
||||
ScriptObjectMirror globalVars)
|
||||
throws IOException, ScriptException, NoSuchMethodException {
|
||||
Map<String, Object> globalMap = (Map<String, Object>) convertIntoJavaObject(globalVars);
|
||||
String dest = CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID();
|
||||
// dump script
|
||||
String jsStr = globalMap.remove("src_" + functionNode.functionName).toString();
|
||||
String scriptPath = dest + File.separator + "contract.js";
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(scriptPath));
|
||||
writer.write(jsStr);
|
||||
writer.close();
|
||||
// dump global variables
|
||||
globalMap.remove("Resources");
|
||||
String globalStr = JsonUtil.toJson(globalMap);
|
||||
String globalPath = dest + File.separator + "global.json";
|
||||
writer = new BufferedWriter(new FileWriter(globalPath));
|
||||
writer.write(globalStr);
|
||||
writer.close();
|
||||
// dump arg and requester
|
||||
Map<String, Object> argMap = new HashMap<>();
|
||||
argMap.put("arg", input.getArg());
|
||||
argMap.put("requester", input.getRequester());
|
||||
String argStr = JsonUtil.toJson(argMap);
|
||||
String argPath = dest + File.separator + "arg.json";
|
||||
writer = new BufferedWriter(new FileWriter(argPath));
|
||||
writer.write(argStr);
|
||||
writer.close();
|
||||
// generate manifest
|
||||
String manifestStr = generateGrapheneManifestStr(engine, input);
|
||||
String manifestPath = dest + File.separator + "nodejs.manifest.template";
|
||||
writer = new BufferedWriter(new FileWriter(manifestPath));
|
||||
writer.write(manifestStr);
|
||||
writer.close();
|
||||
}
|
||||
|
||||
private static Set<String> findAllDependentFunctions(ContractNode cn, FunctionNode fn) {
|
||||
Set<String> dependentFunctions = fn.getDependentFunctions();
|
||||
for (String functionName : dependentFunctions) {
|
||||
for (FunctionNode functionNode : cn.getFunctions()) {
|
||||
if (functionNode.functionName.equals(functionName)) {
|
||||
dependentFunctions.addAll(findAllDependentFunctions(cn, functionNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
dependentFunctions.add(fn.functionName);
|
||||
return dependentFunctions;
|
||||
}
|
||||
|
||||
private static String generateGrapheneManifestStr(Invocable engine, ContractRequest input) throws ScriptException, NoSuchMethodException {
|
||||
String manifestStr = "# Nodejs manifest file example\n" +
|
||||
"#\n" +
|
||||
"# This manifest was prepared and tested on Ubuntu 18.04.\n" +
|
||||
"\n" +
|
||||
"loader.argv0_override = \"nodejs\"\n" +
|
||||
"\n" +
|
||||
"# LibOS layer library of Graphene. There is currently only one implementation,\n" +
|
||||
"# so it is always set to libsysdb.so.\n" +
|
||||
"loader.preload = \"file:$(GRAPHENEDIR)/Runtime/libsysdb.so\"\n" +
|
||||
"\n" +
|
||||
"# Show/hide debug log of Graphene ('inline' or 'none' respectively).\n" +
|
||||
"loader.debug_type = \"$(GRAPHENEDEBUG)\"\n" +
|
||||
"\n" +
|
||||
"# Read application arguments directly from the command line. Don't use this on production!\n" +
|
||||
"loader.insecure__use_cmdline_argv = 1\n" +
|
||||
"\n" +
|
||||
"# Specify paths to search for libraries. The usual LD_LIBRARY_PATH syntax\n" +
|
||||
"# applies. Paths must be in-Graphene visible paths, not host-OS paths (i.e.,\n" +
|
||||
"# paths must be taken from fs.mount.xxx.path, not fs.mount.xxx.uri).\n" +
|
||||
"loader.env.LD_LIBRARY_PATH = \"/lib:/usr/lib:$(ARCH_LIBDIR):/usr/$(ARCH_LIBDIR):./\"\n" +
|
||||
"\n" +
|
||||
"# Mount host-OS directory to required libraries (in 'uri') into in-Graphene\n" +
|
||||
"# visible directory /lib (in 'path').\n" +
|
||||
"fs.mount.lib.type = \"chroot\"\n" +
|
||||
"fs.mount.lib.path = \"/lib\"\n" +
|
||||
"fs.mount.lib.uri = \"file:$(GRAPHENEDIR)/Runtime\"\n" +
|
||||
"\n" +
|
||||
"fs.mount.lib2.type = \"chroot\"\n" +
|
||||
"fs.mount.lib2.path = \"$(ARCH_LIBDIR)\"\n" +
|
||||
"fs.mount.lib2.uri = \"file:$(ARCH_LIBDIR)\"\n" +
|
||||
"\n" +
|
||||
"#fs.mount.lib3.type = \"chroot\"\n" +
|
||||
"#fs.mount.lib3.path = \"/usr/$(ARCH_LIBDIR)\"\n" +
|
||||
"#fs.mount.lib3.uri = \"file:/usr/$(ARCH_LIBDIR)\"\n" +
|
||||
"\n" +
|
||||
"fs.mount.usr.type = \"chroot\"\n" +
|
||||
"fs.mount.usr.path = \"/usr\"\n" +
|
||||
"fs.mount.usr.uri = \"file:/usr\"\n" +
|
||||
"\n" +
|
||||
"# Host-level directory to NSS files required by Glibc + NSS libs\n" +
|
||||
"fs.mount.etc.type = \"chroot\"\n" +
|
||||
"fs.mount.etc.path = \"/etc\"\n" +
|
||||
"fs.mount.etc.uri = \"file:/etc\"\n" +
|
||||
"\n" +
|
||||
"# Workload needs to create temporary files\n" +
|
||||
"fs.mount.tmp.type = \"chroot\"\n" +
|
||||
"fs.mount.tmp.path = \"/tmp\"\n" +
|
||||
"fs.mount.tmp.uri = \"file:/tmp\"\n" +
|
||||
"\n" +
|
||||
"# Set enclave size to 2GB; NodeJS expects around 1.7GB of heap on startup,\n" +
|
||||
"# see e.g. https://github.com/nodejs/node/issues/13018.\n" +
|
||||
"# Recall that SGX v1 requires to specify enclave size at enclave creation time.\n" +
|
||||
"sgx.enclave_size = \"2G\"\n" +
|
||||
"\n" +
|
||||
"# Set maximum number of in-enclave threads (somewhat arbitrarily) to 8. Recall\n" +
|
||||
"# that SGX v1 requires to specify the maximum number of simultaneous threads at\n" +
|
||||
"# enclave creation time.\n" +
|
||||
"sgx.thread_num = 16\n" +
|
||||
"\n" +
|
||||
"# Specify all libraries used by Node.js and its dependencies (including all libs\n" +
|
||||
"# which can be loaded at runtime via dlopen).\n" +
|
||||
"sgx.trusted_files.ld = \"file:$(GRAPHENEDIR)/Runtime/ld-linux-x86-64.so.2\"\n" +
|
||||
"sgx.trusted_files.libc = \"file:$(GRAPHENEDIR)/Runtime/libc.so.6\"\n" +
|
||||
"sgx.trusted_files.libm = \"file:$(GRAPHENEDIR)/Runtime/libm.so.6\"\n" +
|
||||
"sgx.trusted_files.libdl = \"file:$(GRAPHENEDIR)/Runtime/libdl.so.2\"\n" +
|
||||
"sgx.trusted_files.librt = \"file:$(GRAPHENEDIR)/Runtime/librt.so.1\"\n" +
|
||||
"sgx.trusted_files.libutil = \"file:$(GRAPHENEDIR)/Runtime/libutil.so.1\"\n" +
|
||||
"sgx.trusted_files.libpthread = \"file:$(GRAPHENEDIR)/Runtime/libpthread.so.0\"\n" +
|
||||
"sgx.trusted_files.libnssdns = \"file:$(GRAPHENEDIR)/Runtime/libnss_dns.so.2\"\n" +
|
||||
"sgx.trusted_files.libresolv = \"file:$(GRAPHENEDIR)/Runtime/libresolv.so.2\"\n" +
|
||||
"\n" +
|
||||
"sgx.trusted_files.libstdc = \"file:/usr/$(ARCH_LIBDIR)/libstdc++.so.6\"\n" +
|
||||
"sgx.trusted_files.libgccs = \"file:$(ARCH_LIBDIR)/libgcc_s.so.1\"\n" +
|
||||
"sgx.trusted_files.libaptpkg = \"file:/usr/$(ARCH_LIBDIR)/libapt-pkg.so.5.0\"\n" +
|
||||
"sgx.trusted_files.liblz4 = \"file:/usr/$(ARCH_LIBDIR)/liblz4.so.1\"\n" +
|
||||
"sgx.trusted_files.libsystemd = \"file:$(ARCH_LIBDIR)/libsystemd.so.0\"\n" +
|
||||
"sgx.trusted_files.libselinux = \"file:$(ARCH_LIBDIR)/libselinux.so.1\"\n" +
|
||||
"sgx.trusted_files.libgcrypt = \"file:$(ARCH_LIBDIR)/libgcrypt.so.20\"\n" +
|
||||
"sgx.trusted_files.libpcre = \"file:$(ARCH_LIBDIR)/libpcre.so.3\"\n" +
|
||||
"sgx.trusted_files.libgpgerror = \"file:$(ARCH_LIBDIR)/libgpg-error.so.0\"\n" +
|
||||
"sgx.trusted_files.libexpat = \"file:$(ARCH_LIBDIR)/libexpat.so.1\"\n" +
|
||||
"sgx.trusted_files.libz = \"file:$(ARCH_LIBDIR)/libz.so.1\"\n" +
|
||||
"sgx.trusted_files.libz2 = \"file:$(ARCH_LIBDIR)/libbz2.so.1.0\"\n" +
|
||||
"sgx.trusted_files.liblzma = \"file:$(ARCH_LIBDIR)/liblzma.so.5\"\n" +
|
||||
"sgx.trusted_files.libmpdec = \"file:/usr/$(ARCH_LIBDIR)/libmpdec.so.2\"\n" +
|
||||
"\n" +
|
||||
"# Name Service Switch (NSS) libraries (Glibc dependencies)\n" +
|
||||
"sgx.trusted_files.libnssfiles = \"file:$(ARCH_LIBDIR)/libnss_files.so.2\"\n" +
|
||||
"sgx.trusted_files.libnsscompat = \"file:$(ARCH_LIBDIR)/libnss_compat.so.2\"\n" +
|
||||
"sgx.trusted_files.libnssnis = \"file:$(ARCH_LIBDIR)/libnss_nis.so.2\"\n" +
|
||||
"sgx.trusted_files.libnsl = \"file:$(ARCH_LIBDIR)/libnsl.so.1\"\n" +
|
||||
"sgx.trusted_files.libnssmyhostname = \"file:$(ARCH_LIBDIR)/libnss_myhostname.so.2\"\n" +
|
||||
"sgx.trusted_files.libnssmdns = \"file:$(ARCH_LIBDIR)/libnss_mdns4_minimal.so.2\"\n" +
|
||||
"\n" +
|
||||
"# Scratch space\n" +
|
||||
"sgx.allowed_files.tmp = \"file:/tmp\"\n" +
|
||||
"\n" +
|
||||
"# APT config files\n" +
|
||||
"sgx.allowed_files.aptconfd = \"file:/etc/apt/apt.conf.d\"\n" +
|
||||
"sgx.allowed_files.aptconf = \"file:/etc/apt/apt.conf\"\n" +
|
||||
"sgx.allowed_files.apport = \"file:/etc/default/apport\"\n" +
|
||||
"\n" +
|
||||
"# Name Service Switch (NSS) files (Glibc reads these files)\n" +
|
||||
"sgx.allowed_files.nsswitch = \"file:/etc/nsswitch.conf\"\n" +
|
||||
"sgx.allowed_files.group = \"file:/etc/group\"\n" +
|
||||
"sgx.allowed_files.passwd = \"file:/etc/passwd\"\n" +
|
||||
"\n" +
|
||||
"# DNS hostname resolution files (Glibc reads these files)\n" +
|
||||
"sgx.allowed_files.hostconf = \"file:/etc/host.conf\"\n" +
|
||||
"sgx.allowed_files.hosts = \"file:/etc/hosts\"\n" +
|
||||
"sgx.allowed_files.gaiconf = \"file:/etc/gai.conf\"\n" +
|
||||
"sgx.allowed_files.resolv = \"file:/etc/resolv.conf\"\n" +
|
||||
"\n" +
|
||||
"sgx.allowed_files.openssl = \"file:/etc/ssl/openssl.cnf\"\n" +
|
||||
"\n" +
|
||||
"# System's file system table\n" +
|
||||
"sgx.allowed_files.fstab = \"file:/etc/fstab\"\n" +
|
||||
"\n" +
|
||||
"$(NODEJS_TRUSTED_LIBS)\n" +
|
||||
"\n" +
|
||||
"# JavaScript (trusted)\n" +
|
||||
"sgx.allowed_files.smlib = \"file:node_modules\"\n" +
|
||||
"sgx.trusted_files.npminfo = \"file:package.json\"\n" +
|
||||
"sgx.trusted_files.contract = \"file:contract.js\"\n" +
|
||||
"sgx.trusted_files.globaljson = \"file:global.json\"\n" +
|
||||
"sgx.trusted_files.argjson = \"file:arg.json\"\n" +
|
||||
"\n" +
|
||||
"sys.insecure__allow_eventfd = 1\n" +
|
||||
"\n" +
|
||||
"sgx.remote_attestation = 1\n" +
|
||||
"\n" +
|
||||
"loader.env.LD_PRELOAD = \"libsecret_prov_attest.so\"\n" +
|
||||
"loader.env.SECRET_PROVISION_CONSTRUCTOR = \"1\"\n" +
|
||||
"loader.env.SECRET_PROVISION_SET_PF_KEY = \"1\"\n" +
|
||||
"loader.env.SECRET_PROVISION_CA_CHAIN_PATH = \"certs/test-ca-sha256.crt\"\n" +
|
||||
"loader.env.SECRET_PROVISION_SERVERS = \"localhost:4433\"\n" +
|
||||
"\n" +
|
||||
"sgx.trusted_files.libsecretprovattest = \"file:libsecret_prov_attest.so\"\n" +
|
||||
"sgx.trusted_files.cachain = \"file:certs/test-ca-sha256.crt\"\n" +
|
||||
"\n" +
|
||||
"# Specify your SPID and linkable/unlinkable attestation policy\n" +
|
||||
"sgx.ra_client_spid = \"DF3A8BA098E93F66CC64E8A215E98333\"\n" +
|
||||
"sgx.ra_client_linkable = 0\n";
|
||||
// add secret servers
|
||||
manifestStr += "loader.env.SECRET_PROVISION_CC_SERVERS = ";
|
||||
Object resultStr = engine.invokeFunction(
|
||||
"getAllSecret",
|
||||
"",
|
||||
input.getRequester(),
|
||||
input.getRequesterDOI());
|
||||
Map<String, String> resultMap = JsonUtil.fromJson(resultStr.toString(), MapType);
|
||||
Map<String, String> serverMap = JsonUtil.fromJson(resultMap.get("result"), MapType);
|
||||
List<String> entries = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : serverMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String server = entry.getValue();
|
||||
String envVar = "KEY_" + key.substring(0, 10).toUpperCase();
|
||||
entries.add(envVar + "=" + server);
|
||||
}
|
||||
manifestStr += "\"" + String.join(";", entries) + "\"";
|
||||
return manifestStr;
|
||||
}
|
||||
|
||||
private static Object convertIntoJavaObject(Object scriptObj) {
|
||||
if (scriptObj instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror scriptObjectMirror = (ScriptObjectMirror) scriptObj;
|
||||
if (scriptObjectMirror.isArray()) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : scriptObjectMirror.entrySet()) {
|
||||
list.add(convertIntoJavaObject(entry.getValue()));
|
||||
}
|
||||
return list;
|
||||
} else {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : scriptObjectMirror.entrySet()) {
|
||||
map.put(entry.getKey(), convertIntoJavaObject(entry.getValue()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
} else {
|
||||
return scriptObj;
|
||||
}
|
||||
}
|
||||
}
|
884
src/main/java/org/bdware/sc/engine/DesktopEngine.java
Normal file
884
src/main/java/org/bdware/sc/engine/DesktopEngine.java
Normal file
@ -0,0 +1,884 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.analysis.BasicBlock;
|
||||
import org.bdware.analysis.CFGraph;
|
||||
import org.bdware.analysis.gas.Evaluates;
|
||||
import org.bdware.analysis.gas.PPCount;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.ContractResult.Status;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.Contract;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.bean.ProjectConfig;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.boundry.Resources;
|
||||
import org.bdware.sc.boundry.utils.UtilRegistry;
|
||||
import org.bdware.sc.encrypt.HardwareInfo;
|
||||
import org.bdware.sc.encrypt.HardwareInfo.OSType;
|
||||
import org.bdware.sc.event.Event;
|
||||
import org.bdware.sc.event.REvent;
|
||||
import org.bdware.sc.event.REvent.REventSemantics;
|
||||
import org.bdware.sc.node.*;
|
||||
import org.bdware.sc.syncMech.SyncType;
|
||||
import org.bdware.sc.trace.ProgramPointCounter;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.*;
|
||||
|
||||
import javax.script.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class DesktopEngine extends JSEngine {
|
||||
private static final String ScriptFileName = "contract_main.yjs";
|
||||
private static final Logger LOGGER = LogManager.getLogger(DesktopEngine.class);
|
||||
public static boolean _with_init_script = true;
|
||||
// static String script = "";
|
||||
public NashornScriptEngine engine;
|
||||
public SyncMechUtil syncUtil;
|
||||
public boolean recovering; // 如果正在通过trace、trans恢复,设置为true,此时即使是StableMode也不记录
|
||||
Resources resources;
|
||||
// Class<?> clz;
|
||||
// byte[] stub;
|
||||
YJSClassLoader classLoader;
|
||||
private ContractNode cn;
|
||||
private Global global;
|
||||
// private Object obj;
|
||||
// private SimpleScriptContext simpleContext;
|
||||
// private String traceDir;
|
||||
private ContractProcess.Logger tracePS = null;
|
||||
private Contract contract;
|
||||
|
||||
public DesktopEngine() {
|
||||
startEngine();
|
||||
}
|
||||
|
||||
public DesktopEngine(ContractManifest manifest, String zipPath, Contract contract) {
|
||||
File zipFile = new File(zipPath);
|
||||
String dirName = zipFile.getName().replaceAll(".zip$", "").replaceAll(".ypk$", "");
|
||||
File traceDirFile = new File(zipFile.getParent(), dirName);
|
||||
|
||||
this.contract = contract;
|
||||
if (!traceDirFile.exists()) {
|
||||
// traceDirFile.mkdirs();
|
||||
}
|
||||
// traceDir = traceDirFile.getAbsolutePath();
|
||||
startEngine();
|
||||
}
|
||||
|
||||
public static void applyWithGlobal(ScriptFunction script, Global global, Object... obj) {
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != global);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
// System.out.println("[DesktopEngine]" + script.getName() + " -->\n" +
|
||||
// script.safeToString());
|
||||
ScriptRuntime.apply(script, global, obj);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setRecovering(boolean b) {
|
||||
recovering = b;
|
||||
}
|
||||
|
||||
public NashornScriptEngine getNashornEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public Global getDesktopGlobal() {
|
||||
return global;
|
||||
}
|
||||
|
||||
public YJSClassLoader getClassLoad() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public void redirectTracePS(ContractProcess.Logger ps) {
|
||||
TraceType.ps = tracePS = (ps);
|
||||
if (ps instanceof TraceMethod) {
|
||||
TraceType.mTracer = (TraceMethod) ps;
|
||||
}
|
||||
}
|
||||
|
||||
private void startEngine() {
|
||||
try {
|
||||
syncUtil = new SyncMechUtil(this);
|
||||
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
|
||||
ccl = (ccl == null) ? NashornScriptEngineFactory.class.getClassLoader() : ccl;
|
||||
String[] args = new String[]{"--loader-per-compile=false", "-strict=false"};
|
||||
classLoader = new YJSClassLoader(ccl, new YJSFilter());
|
||||
engine =
|
||||
(NashornScriptEngine)
|
||||
new NashornScriptEngineFactory()
|
||||
.getScriptEngine(
|
||||
args, // "--print-ast",
|
||||
// "true",
|
||||
// "-d=/Users/huaqiancai/Downloads/dumpedClz",
|
||||
// "--trace-callsites=enterexit"
|
||||
// "--log=methodhandles:all",
|
||||
// fields:all,
|
||||
// "--print-parse", "true" "--print-code",
|
||||
// fields:finest
|
||||
classLoader);
|
||||
|
||||
Context.TRACEIF = false;
|
||||
// engine = (NashornScriptEngine) new
|
||||
// NashornScriptEngineFactory().getScriptEngine(new YJSFilter());
|
||||
if (_with_init_script) {
|
||||
InputStream in =
|
||||
DesktopEngine.class
|
||||
.getClassLoader()
|
||||
.getResourceAsStream("org/bdware/sc/engine/yancloud_desktop.js");
|
||||
assert in != null;
|
||||
InputStreamReader streamReader = new InputStreamReader(in);
|
||||
engine.getContext()
|
||||
.setAttribute(
|
||||
ScriptEngine.FILENAME,
|
||||
"org/bdware/sc/engine/yancloud_desktop.js",
|
||||
ScriptContext.ENGINE_SCOPE);
|
||||
engine.eval(streamReader);
|
||||
}
|
||||
global = engine.getNashornGlobal();
|
||||
JavaScriptEntry.currentEngine = engine;
|
||||
JavaScriptEntry.currentSyncUtil = syncUtil;
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void initStubClasses() {
|
||||
UtilRegistry.defineUtilClass(classLoader);
|
||||
}
|
||||
|
||||
public void setPermission(List<Permission> setPermission) {
|
||||
initStubClasses();
|
||||
try {
|
||||
StringBuilder yancloud_desktop = new StringBuilder();
|
||||
List<String> permissionStub = Permission.allName();
|
||||
for (Permission permission : setPermission) {
|
||||
yancloud_desktop.append(UtilRegistry.getInitStr(permission.name(), true));
|
||||
permissionStub.remove(permission.name());
|
||||
}
|
||||
for (String str : permissionStub) {
|
||||
yancloud_desktop.append(UtilRegistry.getInitStr(str, false));
|
||||
}
|
||||
// LOGGER.debug("[initScript] " + yancloud_desktop);
|
||||
engine.getContext()
|
||||
.setAttribute(
|
||||
ScriptEngine.FILENAME,
|
||||
yancloud_desktop.toString(),
|
||||
ScriptContext.ENGINE_SCOPE);
|
||||
engine.eval(yancloud_desktop.toString());
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// byte[]中是字节码
|
||||
public Map<String, byte[]> dumpClass() {
|
||||
ScriptLoader loader = engine.getNashornContext().getScriptLoader();
|
||||
Map<String, byte[]> clzCache = loader.getClzCache();
|
||||
Map<String, byte[]> ret = new HashMap<>(clzCache);
|
||||
// for (String str : clzCache.keySet()) {
|
||||
// System.out.println("===ScriptClzName:" + str);
|
||||
// }
|
||||
StructureLoader sLoader = (StructureLoader) (engine.getNashornContext().getStructLoader());
|
||||
clzCache = sLoader.getClzCache();
|
||||
// for (String str : clzCache.keySet()) {
|
||||
// System.out.println("===StructureClzName:" + str);
|
||||
// }
|
||||
ret.putAll(clzCache);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void registerResource(Resources resources) {
|
||||
Invocable cal = engine;
|
||||
this.resources = resources;
|
||||
try {
|
||||
cal.invokeFunction("defineProp", "Resources", resources);
|
||||
} catch (NoSuchMethodException | ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Resources getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContractResult loadContract(
|
||||
Contract contract, ContractNode contractNode, boolean isInsnLimit) {
|
||||
LOGGER.info("loadContract isInsnLimit:" + isInsnLimit);
|
||||
cn = contractNode;
|
||||
engine.getContext()
|
||||
.setAttribute(ScriptEngine.FILENAME, ScriptFileName, ScriptContext.ENGINE_SCOPE);
|
||||
try {
|
||||
setPermission(cn.getPermission());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (FunctionNode fun : contractNode.getFunctions())
|
||||
try {
|
||||
String str = fun.plainText();
|
||||
engine.getContext()
|
||||
.setAttribute(
|
||||
ScriptEngine.FILENAME,
|
||||
fun.getFileName(),
|
||||
ScriptContext.ENGINE_SCOPE);
|
||||
compileFunction(str, isInsnLimit);
|
||||
} catch (ScriptException e) {
|
||||
return wrapperException(e, fun);
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
e.printStackTrace();
|
||||
return new ContractResult(Status.Error, new JsonPrimitive(bo.toString()));
|
||||
}
|
||||
LOGGER.debug(JsonUtil.toJson(contractNode.events));
|
||||
for (String event : contractNode.events.keySet()) {
|
||||
try {
|
||||
String str;
|
||||
REventSemantics semantics = contractNode.events.get(event);
|
||||
if (REventSemantics.AT_LEAST_ONCE.equals(semantics)) {
|
||||
str =
|
||||
String.format(
|
||||
"function %s(arg) { YancloudUtil.pubEvent(\"%s\", arg); }",
|
||||
event, event);
|
||||
} else {
|
||||
str =
|
||||
String.format(
|
||||
"function %s(arg) { YancloudUtil.pubEventConstraint(\"%s\", arg, \"%s\"); }",
|
||||
event, event, semantics.name());
|
||||
}
|
||||
compileFunction(str, false);
|
||||
str =
|
||||
String.format(
|
||||
"function %ss(arg0, arg1) { YancloudUtil.pubEventConstraint(\"%s\", arg0, arg1); }",
|
||||
event, event);
|
||||
compileFunction(str, false);
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (ClassNode cn : contractNode.getClzs()) {
|
||||
try {
|
||||
System.out.println(cn.plainText());
|
||||
// engine.eval(cn.plainText());
|
||||
} catch (Exception e) {
|
||||
// return wrapperException(e, cn.getFileName(), cn.getLine(),
|
||||
// cn.getPos());
|
||||
}
|
||||
}
|
||||
ScriptObjectMirror globalVars = (ScriptObjectMirror) engine.get("Global");
|
||||
ConfidentialContractUtil.generateConfidentialContract(cn, globalVars, global);
|
||||
ContractResult cResult =
|
||||
new ContractResult(Status.Success, new JsonPrimitive(contract.getPublicKey()));
|
||||
cResult.isInsnLimit = isInsnLimit;
|
||||
return cResult;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Load a contract into contract engine
|
||||
// *
|
||||
// * @param contractNode a contract node generated by YJS compiler
|
||||
// * @return whether contract is loaded successfully
|
||||
// */
|
||||
// @Override
|
||||
// public ContractResult loadContract(Contract contract, ContractNode contractNode) {
|
||||
// cn = contractNode;
|
||||
// engine.getContext()
|
||||
// .setAttribute(ScriptEngine.FILENAME, ScriptFileName,
|
||||
// ScriptContext.ENGINE_SCOPE);
|
||||
// try {
|
||||
// setPermission(cn.getPermission());
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// for (FunctionNode fun : cn.getFunctions()) {
|
||||
// try {
|
||||
// String str = fun.plainText();
|
||||
// engine.getContext()
|
||||
// .setAttribute(
|
||||
// ScriptEngine.FILENAME,
|
||||
// fun.getFileName(),
|
||||
// ScriptContext.ENGINE_SCOPE);
|
||||
// Object scriptFunction = engine.eval(str);
|
||||
// ScriptObjectMirror sf = (ScriptObjectMirror) scriptFunction;
|
||||
// compileFunction(sf, fun.getLogTypes().contains(LogType.Branch));
|
||||
// } catch (ScriptException e) {
|
||||
// return wrapperException(e, fun);
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// e.printStackTrace();
|
||||
// return new ContractResult(Status.Error, new JsonPrimitive(bo.toString()));
|
||||
// }
|
||||
// }
|
||||
// for (String event : cn.events) {
|
||||
// String str =
|
||||
// "function "
|
||||
// + event
|
||||
// + "(arg){ return YancloudUtil.pubEvent(\""
|
||||
// + event
|
||||
// + "\",arg);}";
|
||||
//
|
||||
// try {
|
||||
// Object scriptFunction = engine.eval(str);
|
||||
// ScriptObjectMirror sf = (ScriptObjectMirror) scriptFunction;
|
||||
// compileFunction(sf, false);
|
||||
// } catch (ScriptException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (ClassNode classNode : cn.getClzs()) {
|
||||
// try {
|
||||
// System.out.println(classNode.plainText());
|
||||
// // engine.eval(cn.plainText());
|
||||
// } catch (Exception e) {
|
||||
// // return wrapperException(e, cn.getFileName(), cn.getLine(),
|
||||
// // cn.getPos());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // dump confidential functions and corresponding dependent functions to a String in
|
||||
// Global
|
||||
// // variable.
|
||||
// // The String will be passed to collect signature.
|
||||
//
|
||||
// return new ContractResult(Status.Success, new JsonPrimitive(""));
|
||||
// }
|
||||
private void compileFunction(ScriptObjectMirror sf, boolean instrumentBranch) {
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != global);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
if (instrumentBranch) {
|
||||
Context.TRACEIF = true;
|
||||
Context.TRACEMETHOD = true;
|
||||
}
|
||||
sf.compileScriptFunction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (globalChanged) Context.setGlobal(oldGlobal);
|
||||
Context.TRACEIF = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void compileFunction(String snippet, boolean instrumentBranch) throws ScriptException {
|
||||
compileFunction((ScriptObjectMirror) engine.eval(snippet), instrumentBranch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ContractResult executeContract(ContractRequest input) {
|
||||
ContractProcess.Logger previous = this.getTracePS();
|
||||
ByteArrayOutputStream bo = null;
|
||||
if (syncUtil.startFlag && syncUtil.currType == SyncType.Trace && !recovering) {
|
||||
syncUtil.traceRecordUtil.startNext();
|
||||
} else if (syncUtil.startFlag && syncUtil.currType == SyncType.Trans && !recovering) {
|
||||
if (input.needSeq) {
|
||||
syncUtil.transRecordUtil.startNext(input.getAction(), input.getArg(), input.seq);
|
||||
} else {
|
||||
syncUtil.transRecordUtil.startNext(input.getAction(), input.getArg());
|
||||
}
|
||||
}
|
||||
// TODO remove this in executeContract, using getFunctionNodes in ContractManger instead.
|
||||
if (input.getAction().equals("getFunctionNodes")) {
|
||||
return getFunctionNodes();
|
||||
}
|
||||
JavaScriptEntry.msgList = new ArrayList<>();
|
||||
FunctionNode fun = cn.getFunction(input.getAction());
|
||||
ProgramPointCounter ppc = null;
|
||||
try {
|
||||
if (fun.getCost() != null && fun.getCost().isCountGas()) {
|
||||
List<String> functions = new ArrayList<>();
|
||||
for (FunctionNode fn : cn.getFunctions()) {
|
||||
if (fn.isExport()) {
|
||||
functions.add(fn.functionName);
|
||||
}
|
||||
}
|
||||
int functionIndex = functions.indexOf(input.getAction());
|
||||
// TODO calculate ppCountMap at loading time?
|
||||
HashMap<String, Long> ppCountMap = evaluatesAnalysis(input.getAction(), functions);
|
||||
Long extraGas = getExtraGas(fun.getCost().getExtraGas(), input);
|
||||
bo = new ByteArrayOutputStream();
|
||||
ppc =
|
||||
new ProgramPointCounter(
|
||||
bo,
|
||||
previous.getCp(),
|
||||
Long.MAX_VALUE,
|
||||
functionIndex,
|
||||
input.getGasLimit(),
|
||||
extraGas,
|
||||
input.getAction(),
|
||||
ppCountMap);
|
||||
this.redirectTracePS(ppc);
|
||||
}
|
||||
Invocable cal = engine;
|
||||
if (fun.isExport()
|
||||
// if the function has been registered as event handler
|
||||
|| (fun.isHandler()
|
||||
&& (input.getRequester().length() == 40
|
||||
|| input.getRequester().equals("event")))) {
|
||||
Object ret = null;
|
||||
// long start = System.currentTimeMillis();
|
||||
|
||||
for (AnnotationHook handler : fun.beforeExecutionAnnotations()) {
|
||||
|
||||
ret = handler.handle(input, this, ret);
|
||||
}
|
||||
// actually invoke!
|
||||
if (ret == null) {
|
||||
ret =
|
||||
cal.invokeFunction(
|
||||
input.getAction(),
|
||||
(fun.isHandler()
|
||||
? JsonUtil.fromJson(input.getArg(), Event.class)
|
||||
: input.getArg()),
|
||||
input.getRequester(),
|
||||
input.getRequesterDOI());
|
||||
}
|
||||
for (AnnotationHook handler : fun.afterExecutionAnnotations()) {
|
||||
//Mask在after裏面
|
||||
//System.out.println("afterHook"+contract.Mask);
|
||||
|
||||
ret = handler.handle(input, this, ret);
|
||||
}
|
||||
//System.out.println("[DesktopEngine MaskConfig]"+ContractProcess.instance.getProjectConfig().getMaskConfig().config.toString());
|
||||
ContractResult contractRes = new ContractResult(Status.Success, (JsonElement) ret);
|
||||
if (ppc != null) {
|
||||
contractRes.extraGas = ppc.extraGas;
|
||||
contractRes.executionGas = ppc.cost;
|
||||
contractRes.totalGas = ppc.extraGas + ppc.cost;
|
||||
}
|
||||
if (bo != null) {
|
||||
contractRes.analysis = bo.toString();
|
||||
}
|
||||
|
||||
if (fun.getLogTypes().contains(LogType.Branch)) {
|
||||
contractRes.branch = tracePS.getOutputStr();
|
||||
}
|
||||
|
||||
List<REvent> msgList = JavaScriptEntry.msgList;
|
||||
JavaScriptEntry.msgList = null;
|
||||
if (!msgList.isEmpty()) {
|
||||
contractRes.events = msgList;
|
||||
contractRes.eventRelated = true;
|
||||
}
|
||||
|
||||
if (fun.isHandler() && input.getRequester().length() == 40) {
|
||||
contractRes.eventRelated = true;
|
||||
}
|
||||
if (syncUtil.startFlag && !recovering) {
|
||||
switch (syncUtil.currType) {
|
||||
case Trace:
|
||||
syncUtil.traceRecordUtil.eachFinish();
|
||||
break;
|
||||
case Trans:
|
||||
syncUtil.transRecordUtil.eachFinish();
|
||||
break;
|
||||
case Memory:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return contractRes;
|
||||
} else {
|
||||
// return new ContractResult(Status.Exception, "Action " + input.getAction() + "
|
||||
// is not exported!");
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive("Action " + input.getAction() + " is not exported!"));
|
||||
}
|
||||
|
||||
} catch (ScriptException e) {
|
||||
Throwable cause = e.getCause();
|
||||
e.printStackTrace();
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive(extractException(e.getMessage(), extract(cn, cause))));
|
||||
} catch (Throwable e) {
|
||||
ByteArrayOutputStream bo1 = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(bo1);
|
||||
e.printStackTrace(ps);
|
||||
e.printStackTrace();
|
||||
if (e.getCause() != null && e.getCause() instanceof ScriptException) {
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive(
|
||||
extractException(bo1.toString(), extract(cn, e.getCause()))));
|
||||
} else {
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive(extractException(bo1.toString(), extract(cn, e))));
|
||||
}
|
||||
} finally {
|
||||
this.redirectTracePS(previous);
|
||||
}
|
||||
}
|
||||
|
||||
private String extractException(String msg, List<String> stack) {
|
||||
int endIndex = Math.min(msg.indexOf("in"), msg.length());
|
||||
StringBuilder msb = new StringBuilder(msg.substring(0, endIndex));
|
||||
for (String str : stack) {
|
||||
msb.append("\n").append(str);
|
||||
}
|
||||
return msb.toString();
|
||||
}
|
||||
|
||||
private HashMap<String, Long> evaluatesAnalysis(String getFunction, List<String> functions) {
|
||||
// System.out.println("当前的function:" + getFunction);
|
||||
HashMap<String, CFGraph> CFGmap = new HashMap<>();
|
||||
HashMap<String, Long> ppCountMap = new HashMap<>();
|
||||
Map<String, byte[]> clzs = this.dumpClass();
|
||||
Map<String, MethodNode> methods = new HashMap<>();
|
||||
for (byte[] clz : clzs.values()) {
|
||||
org.objectweb.asm.tree.ClassNode classNode = new org.objectweb.asm.tree.ClassNode();
|
||||
ClassReader cr = new ClassReader(clz);
|
||||
cr.accept(classNode, ClassReader.EXPAND_FRAMES);
|
||||
for (MethodNode mn : classNode.methods) {
|
||||
methods.put(mn.name, mn);
|
||||
}
|
||||
}
|
||||
int flag = 0;
|
||||
for (String function : functions) {
|
||||
MethodNode mn = methods.get(function);
|
||||
if (mn != null) {
|
||||
CFGraph cfg =
|
||||
new CFGraph(mn) {
|
||||
@Override
|
||||
public BasicBlock getBasicBlock(int id) {
|
||||
return new BasicBlock(id);
|
||||
}
|
||||
};
|
||||
// cfg.printSelf();
|
||||
CFGmap.put(function, cfg);
|
||||
PPCount countFee = new PPCount(cfg, flag);
|
||||
|
||||
BasicBlock bb = cfg.getBasicBlockAt(0);
|
||||
countFee.dfs(cfg, bb);
|
||||
// System.out.println("[ppmap]:" + PPCount.ppMap);
|
||||
// System.out.println("[PPCount.branchCount]"+PPCount.branchCount);
|
||||
Evaluates feEvaluates = new Evaluates();
|
||||
feEvaluates.getGas(PPCount.branchCount);
|
||||
feEvaluates.getInsnGas(PPCount.ppMap);
|
||||
|
||||
PPCount.countFunction(function, Evaluates.map);
|
||||
ppCountMap = Evaluates.map;
|
||||
// System.out.println("+++++++" + PPCount.ppMap);
|
||||
flag++;
|
||||
}
|
||||
}
|
||||
/* for (Map.Entry<String, Long> map : PPCount.functionSumGas.entrySet()) {
|
||||
if (map.getKey().contains(getFunction) && map.getKey().contains("true")) {
|
||||
System.out.println("[合约方法pub中条件循环为true时:]" + map.getValue());
|
||||
} else if (map.getKey().contains(getFunction) && map.getKey().contains("false")) {
|
||||
System.out.println("[合约方法pub中条件循环为false时:]" + map.getValue());
|
||||
} else if (map.getKey().contains(getFunction)) {
|
||||
System.out.println("[合约方法pub中其他语句消耗:]" + map.getValue());
|
||||
}
|
||||
}*/
|
||||
return ppCountMap;
|
||||
}
|
||||
|
||||
private Long getExtraGas(String costFunction, ContractRequest input)
|
||||
throws ScriptException, NoSuchMethodException {
|
||||
if (costFunction == null || costFunction.equals("")) {
|
||||
return 0L;
|
||||
}
|
||||
Invocable cal = engine;
|
||||
Object ret =
|
||||
cal.invokeFunction(
|
||||
costFunction,
|
||||
input.getArg(),
|
||||
input.getRequester(),
|
||||
input.getRequesterDOI());
|
||||
if (ret != null && StringUtils.isNumeric(ret.toString())) {
|
||||
return Long.parseLong(ret.toString());
|
||||
} else {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
private ContractResult getFunctionNodes() {
|
||||
String msg = JsonUtil.toJson(cn.getFunctions());
|
||||
return new ContractResult(Status.Exception, new JsonPrimitive(msg));
|
||||
}
|
||||
|
||||
private void dump(Class<?> clz) {
|
||||
try {
|
||||
String name = clz.getCanonicalName().replace(".", "/") + ".class";
|
||||
System.out.println("DumpClzz:" + clz.getCanonicalName() + " -->" + name);
|
||||
name = "/Script.class";
|
||||
|
||||
InputStream input = clz.getClassLoader().getResourceAsStream(name);
|
||||
FileOutputStream fout =
|
||||
new FileOutputStream("./output/" + clz.getCanonicalName() + ".class");
|
||||
byte[] arr = new byte[1024];
|
||||
int l;
|
||||
assert input != null;
|
||||
while ((l = input.read(arr)) > 0) {
|
||||
fout.write(arr, 0, l);
|
||||
}
|
||||
fout.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private LinkedHashMap<?, ?> getClassCache(Context c) {
|
||||
try {
|
||||
Field f = c.getClass().getDeclaredField("classCache");
|
||||
f.setAccessible(true);
|
||||
Object classCache = f.get(c);
|
||||
return (LinkedHashMap<?, ?>) classCache;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ContractResult wrapperException(ScriptException e, FunctionNode fun) {
|
||||
int line = fun.getLine();
|
||||
int pos = fun.getPos();
|
||||
StringBuilder content = new StringBuilder();
|
||||
String message = e.getMessage();
|
||||
message = message.replaceFirst("^[^:]*:[^:]*:[^ ]* ", "");
|
||||
int actLine = e.getLineNumber();
|
||||
if (actLine != -1) {
|
||||
actLine += line - 1;
|
||||
}
|
||||
message =
|
||||
message.replaceAll(
|
||||
"at line number " + e.getLineNumber(), "at line number " + (actLine));
|
||||
if (fun.getFileName() != null)
|
||||
message = message.replace("in contract_main.yjs", "in " + fun.getFileName());
|
||||
content.append(message);
|
||||
content.append("(");
|
||||
if (fun.functionName != null) content.append(fun.functionName);
|
||||
else content.append("contract_main.yjs");
|
||||
content.append(":");
|
||||
|
||||
content.append(actLine);
|
||||
content.append(":").append(pos).append(")");
|
||||
return new ContractResult(Status.Exception, new JsonPrimitive(content.toString()));
|
||||
}
|
||||
|
||||
private List<String> extract(ContractNode c, Throwable cause) {
|
||||
StackTraceElement[] stack = cause.getStackTrace();
|
||||
List<String> ret = new ArrayList<>();
|
||||
for (StackTraceElement element : stack) {
|
||||
|
||||
if (element == null || element.getFileName() == null) {
|
||||
continue;
|
||||
}
|
||||
String methodName = element.getMethodName();
|
||||
String fileName = element.getFileName();
|
||||
|
||||
if (fileName.endsWith(".java")) continue;
|
||||
if (c.isBundle()) {
|
||||
fileName = fixFile(c, methodName);
|
||||
}
|
||||
if (fileName.equals("--")) continue;
|
||||
ret.add(
|
||||
String.format(
|
||||
"at %s(%s:%d)",
|
||||
methodName,
|
||||
fileName,
|
||||
(fixLine(c, methodName) + element.getLineNumber())));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private String fixFile(ContractNode c, String methodName) {
|
||||
return c.queryFile(methodName);
|
||||
}
|
||||
|
||||
private int fixLine(ContractNode c, String methodName) {
|
||||
return c.queryLine(methodName) - 1;
|
||||
}
|
||||
|
||||
public Global getGlobal() {
|
||||
return engine.getNashornGlobal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(String script, ScriptContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(Reader reader, ScriptContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(String script) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(Reader reader) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(String script, Bindings n) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(Reader reader, Bindings n) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String key, Object value) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String key) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings getBindings(int scope) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBindings(Bindings bindings, int scope) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings createBindings() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptContext getContext() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(ScriptContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngineFactory getFactory() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void loadJar(ZipFile zf) {
|
||||
YJSClassLoader loader = getAppLoader();
|
||||
Enumeration<? extends ZipEntry> entries = zf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
assert null != loader;
|
||||
if (entry.getName().endsWith(".jar")) {
|
||||
System.out.println("[DesktopEngine] loadJar:" + entry.getName());
|
||||
System.out.println("[DesktopEngine] classLoader:" + getClassLoad());
|
||||
|
||||
loader.loadJar(zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
}
|
||||
if (entry.getName().endsWith(".so") || entry.getName().endsWith(".so.1")) {
|
||||
System.out.println("unzip library:" + entry.getName().replaceAll(".*/", ""));
|
||||
loader.unzipLibrary(
|
||||
zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
}
|
||||
if (HardwareInfo.type == OSType.mac && entry.getName().endsWith(".dylib")) {
|
||||
System.out.println("unzip library:" + entry.getName().replaceAll(".*/", ""));
|
||||
loader.unzipLibrary(
|
||||
zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != loader) {
|
||||
loader.loadLibraries();
|
||||
}
|
||||
}
|
||||
|
||||
private YJSClassLoader getAppLoader() {
|
||||
try {
|
||||
Field f = engine.getClass().getDeclaredField("nashornContext");
|
||||
f.setAccessible(true);
|
||||
Context c = (Context) f.get(engine);
|
||||
Method m = Context.class.getDeclaredMethod("getAppLoader");
|
||||
m.setAccessible(true);
|
||||
return (YJSClassLoader) m.invoke(c);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void initManifest(ContractManifest manifest) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public ContractProcess.Logger getTracePS() {
|
||||
return tracePS;
|
||||
}
|
||||
|
||||
public Contract getContract() {
|
||||
return this.contract;
|
||||
}
|
||||
|
||||
public ProjectConfig getProjectConfig() {
|
||||
return ContractProcess.instance.getProjectConfig();
|
||||
}
|
||||
}
|
101
src/main/java/org/bdware/sc/engine/JSONTool.java
Normal file
101
src/main/java/org/bdware/sc/engine/JSONTool.java
Normal file
@ -0,0 +1,101 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import com.google.gson.*;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class JSONTool {
|
||||
private static Set<Object> recorded = null;
|
||||
|
||||
public static JsonElement copy(ScriptObjectMirror ret2) {
|
||||
recorded = new HashSet<>();
|
||||
JsonElement jsonElement = copyInternal(ret2);
|
||||
recorded.clear();
|
||||
;
|
||||
return jsonElement;
|
||||
}
|
||||
|
||||
private static JsonElement copyInternal(Object obj) {
|
||||
if (recorded.contains(obj)) return JsonNull.INSTANCE;
|
||||
if (obj == null) return JsonNull.INSTANCE;
|
||||
if (obj.getClass() == wrp.jdk.nashorn.internal.runtime.Undefined.class)
|
||||
return JsonNull.INSTANCE;
|
||||
if (obj.getClass() == ScriptObjectMirror.class) {
|
||||
recorded.add(obj);
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) obj;
|
||||
if (som.isFunction()) {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
if (som.isArray()) {
|
||||
JsonArray jarray = new JsonArray();
|
||||
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
try {
|
||||
if (Integer.parseInt(str) >= 0)
|
||||
jarray.add(copyInternal(som.getMember(str)));
|
||||
} catch (Exception e) {
|
||||
// System.out.println("[JSONTool] ignore key:"+str);
|
||||
}
|
||||
}
|
||||
return jarray;
|
||||
} else {
|
||||
JsonObject jo = new JsonObject();
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
jo.add(str, copyInternal(som.getMember(str)));
|
||||
}
|
||||
return jo;
|
||||
}
|
||||
} else if (obj.getClass() == jdk.nashorn.api.scripting.ScriptObjectMirror.class) {
|
||||
recorded.add(obj);
|
||||
jdk.nashorn.api.scripting.ScriptObjectMirror som =
|
||||
(jdk.nashorn.api.scripting.ScriptObjectMirror) obj;
|
||||
if (som.isFunction()) {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
if (som.isArray()) {
|
||||
JsonArray jarray = new JsonArray();
|
||||
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
try {
|
||||
if (Integer.parseInt(str) >= 0)
|
||||
jarray.add(copyInternal(som.getMember(str)));
|
||||
} catch (Exception e) {
|
||||
// System.out.println("[JSONTool] ignore key:"+str);
|
||||
}
|
||||
}
|
||||
return jarray;
|
||||
} else {
|
||||
JsonObject jo = new JsonObject();
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
jo.add(str, copyInternal(som.getMember(str)));
|
||||
}
|
||||
return jo;
|
||||
}
|
||||
} else if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else if (obj instanceof Number) {
|
||||
return new JsonPrimitive((Number) obj);
|
||||
|
||||
} else if (obj instanceof String) {
|
||||
return new JsonPrimitive((String) obj);
|
||||
|
||||
} else if (obj instanceof Character) {
|
||||
return new JsonPrimitive((Character) obj);
|
||||
}
|
||||
if (obj instanceof Boolean) {
|
||||
return new JsonPrimitive((Boolean) obj);
|
||||
}
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
|
||||
public static JsonElement copy(jdk.nashorn.api.scripting.ScriptObjectMirror res) {
|
||||
recorded = new HashSet<>();
|
||||
JsonElement jsonElement = copyInternal(res);
|
||||
recorded.clear();
|
||||
;
|
||||
return jsonElement;
|
||||
}
|
||||
}
|
301
src/main/java/org/bdware/sc/engine/SyncMechUtil.java
Normal file
301
src/main/java/org/bdware/sc/engine/SyncMechUtil.java
Normal file
@ -0,0 +1,301 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.memory.MemoryDumpUtil;
|
||||
import org.bdware.sc.memory.MemoryRecoverUtil;
|
||||
import org.bdware.sc.redo.TransRecordUtil;
|
||||
import org.bdware.sc.redo.TransRecoverUtil;
|
||||
import org.bdware.sc.syncMech.SyncRecord;
|
||||
import org.bdware.sc.syncMech.SyncType;
|
||||
import org.bdware.sc.trace.TraceRecordUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/*
|
||||
* 决策使用什么机制记录
|
||||
*/
|
||||
public class SyncMechUtil {
|
||||
private static final Logger LOGGER = LogManager.getLogger(SyncMechUtil.class);
|
||||
public AtomicInteger filedTrans; // 记录到文件中的trans数
|
||||
|
||||
public Boolean startFlag = false;
|
||||
public List<SyncRecord> syncRecords;
|
||||
// public List<SyncRecord> syncRecoverRecords;
|
||||
public SyncType currType;
|
||||
|
||||
public MemoryDumpUtil memoryDumpUtil;
|
||||
public MemoryRecoverUtil memoryRecoverUtil;
|
||||
public TraceRecordUtil traceRecordUtil;
|
||||
// public TraceRecoverUtil traceRecoverUtil;
|
||||
public TransRecordUtil transRecordUtil;
|
||||
public TransRecoverUtil transRecoverUtil;
|
||||
|
||||
public DesktopEngine engine;
|
||||
public String contractID;
|
||||
public String syncFileName;
|
||||
public String dir;
|
||||
public String memoryDir;
|
||||
public String traceDir;
|
||||
public String transDir;
|
||||
public String syncDir;
|
||||
public String crDir; // ContractRecord dir
|
||||
|
||||
public SyncMechUtil(DesktopEngine en) {
|
||||
this.engine = en;
|
||||
}
|
||||
|
||||
/*
|
||||
* 路径操作
|
||||
*/
|
||||
public void setDir(String str) {
|
||||
this.dir = str;
|
||||
String[] strs = str.split("/");
|
||||
this.contractID = strs[strs.length - 1];
|
||||
setMemoryDir(dir + "memory");
|
||||
setTraceDir(dir + "trace");
|
||||
setTransDir(dir + "trans");
|
||||
setSyncDir(dir + "sync");
|
||||
setCrDir(dir + "cr");
|
||||
}
|
||||
|
||||
public void setMemoryDir(String dir) {
|
||||
this.memoryDir = dir;
|
||||
File f = new File(memoryDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTraceDir(String dir) {
|
||||
this.traceDir = dir;
|
||||
File f = new File(traceDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTransDir(String dir) {
|
||||
this.transDir = dir;
|
||||
File f = new File(transDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSyncDir(String dir) {
|
||||
this.syncDir = dir;
|
||||
File f = new File(syncDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCrDir(String dir) {
|
||||
this.crDir = dir;
|
||||
File f = new File(crDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAllFiles() {
|
||||
File file = new File(syncDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(crDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(memoryDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(traceDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(transDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* memory的操作
|
||||
* 无需startFlag就可以使用memory的操作
|
||||
*/
|
||||
public synchronized String dumpMemory(String path) {
|
||||
if (memoryDumpUtil == null) memoryDumpUtil = new MemoryDumpUtil(engine.engine);
|
||||
return memoryDumpUtil.dumpMemory(path, true);
|
||||
}
|
||||
|
||||
public synchronized String dumpMemory(String path, boolean stateful) {
|
||||
LOGGER.info("dumpMemroy : stateful=" + stateful);
|
||||
if (memoryDumpUtil == null) memoryDumpUtil = new MemoryDumpUtil(engine.engine);
|
||||
return memoryDumpUtil.dumpMemory(path, stateful);
|
||||
}
|
||||
|
||||
public synchronized String loadMemoryDump(String path) {
|
||||
if (memoryRecoverUtil == null)
|
||||
memoryRecoverUtil = new MemoryRecoverUtil(engine.engine, engine.resources);
|
||||
memoryRecoverUtil.loadMemory(path, true);
|
||||
return "success";
|
||||
}
|
||||
|
||||
public synchronized String loadMemoryDump(String path, boolean stateful) {
|
||||
LOGGER.info("loadMemroy : stateful=" + stateful);
|
||||
if (memoryRecoverUtil == null)
|
||||
memoryRecoverUtil = new MemoryRecoverUtil(engine.engine, engine.resources);
|
||||
memoryRecoverUtil.loadMemory(path, stateful);
|
||||
return "success";
|
||||
}
|
||||
|
||||
/*
|
||||
* 同步机制操作
|
||||
*/
|
||||
// 设置ContractRecord持久化的文件
|
||||
public void setCRFile(String fileName) {
|
||||
syncFileName = fileName.substring(15);
|
||||
File file = new File(syncDir + "/" + syncFileName);
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
pw.println(fileName);
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setStartFlag(boolean b) {
|
||||
synchronized (startFlag) {
|
||||
if (startFlag == b && !b) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.startFlag = b;
|
||||
if (startFlag) { // start
|
||||
// 如果之前start过了,此次start就是一个检查点
|
||||
|
||||
filedTrans = new AtomicInteger(-1);
|
||||
syncRecords = new ArrayList<>();
|
||||
// dump current
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH_mm_ss");
|
||||
String path = format.format(new Date()) + "_" + new Random().nextInt();
|
||||
String state = dumpMemory(memoryDir + "/" + path);
|
||||
|
||||
syncRecords.add(new SyncRecord(SyncType.Memory, path));
|
||||
|
||||
changeCurrType(SyncType.Trans);
|
||||
path = format.format(new Date()) + "_" + new Random().nextInt();
|
||||
transRecordUtil.setFileName(path);
|
||||
syncRecords.add(new SyncRecord(SyncType.Trans, path));
|
||||
|
||||
// write syncRecords
|
||||
appendSyncFile(syncFileName, 0, 1);
|
||||
} else { // stop
|
||||
clearAllFiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void changeCurrType(SyncType t) {
|
||||
if (t == currType) return;
|
||||
|
||||
// finASyncRecord();
|
||||
currType = t;
|
||||
switch (currType) {
|
||||
case Trace:
|
||||
if (traceRecordUtil == null) {
|
||||
traceRecordUtil = new TraceRecordUtil(engine, this);
|
||||
}
|
||||
break;
|
||||
case Trans:
|
||||
if (transRecordUtil == null) {
|
||||
transRecordUtil = new TransRecordUtil(engine, this);
|
||||
}
|
||||
break;
|
||||
case Memory:
|
||||
if (memoryDumpUtil == null) memoryDumpUtil = new MemoryDumpUtil(engine.engine);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// startASyncRecord();
|
||||
}
|
||||
|
||||
// 追加写sync文件
|
||||
public void appendSyncFile(String fileName, int start, int end) {
|
||||
File file = new File(syncDir + "/" + fileName);
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
for (int i = start; i <= end; i++) {
|
||||
pw.println(syncRecords.get(i).getContent());
|
||||
}
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Trans操作
|
||||
*/
|
||||
public synchronized String redo(String path) {
|
||||
if (transRecoverUtil == null) transRecoverUtil = new TransRecoverUtil(engine);
|
||||
|
||||
// 先清空,否则会重复执行一些trans
|
||||
if (transRecoverUtil.transRecords != null && !transRecoverUtil.transRecords.isEmpty())
|
||||
transRecoverUtil.transRecords.clear();
|
||||
|
||||
// 某一次检查点之后没有transRecords
|
||||
File file = new File(path);
|
||||
if (!file.exists()) return "success";
|
||||
|
||||
transRecoverUtil.setTraceRecords(path);
|
||||
transRecoverUtil.recoverFromTransRecord();
|
||||
return "success";
|
||||
}
|
||||
}
|
21
src/main/java/org/bdware/sc/engine/TestClassFilter.java
Normal file
21
src/main/java/org/bdware/sc/engine/TestClassFilter.java
Normal file
@ -0,0 +1,21 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
|
||||
public class TestClassFilter {
|
||||
public TestClassFilter() {
|
||||
final String script = "print(java.lang.System.getProperty(\"java.home\"));" +
|
||||
"print(\"Create file variable\");" +
|
||||
"var File = Java.type(\"java.io.File\");";
|
||||
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
ScriptEngine engine = factory.getScriptEngine(new YJSFilter());
|
||||
try {
|
||||
engine.eval(script);
|
||||
System.out.print("test push in");
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception caught:" + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
105
src/main/java/org/bdware/sc/engine/YJSClassLoader.java
Normal file
105
src/main/java/org/bdware/sc/engine/YJSClassLoader.java
Normal file
@ -0,0 +1,105 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.ClassFilter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class YJSClassLoader extends URLClassLoader {
|
||||
ClassFilter classFilter;
|
||||
File libDir = null;
|
||||
List<String> toLoad = new ArrayList<>();
|
||||
|
||||
public YJSClassLoader(ClassLoader parent, ClassFilter cf) {
|
||||
super(new URL[]{}, parent);
|
||||
classFilter = cf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> findClass(final String fullName) throws ClassNotFoundException {
|
||||
if (classFilter != null && !classFilter.exposeToScripts(fullName)) {
|
||||
throw new ClassNotFoundException(fullName);
|
||||
}
|
||||
return super.findClass(fullName);
|
||||
}
|
||||
|
||||
public Class<?> defineStubClass(String name, byte[] bytes) {
|
||||
return defineClass(name, bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
public void loadJar(InputStream inputStream, String path) {
|
||||
String fileName = unzipLibrary(inputStream, path);
|
||||
try {
|
||||
super.addURL(new File(fileName).toURI().toURL());
|
||||
} catch (MalformedURLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] asByteArray(InputStream in) {
|
||||
try {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
byte[] buff = new byte[1024];
|
||||
|
||||
for (int len = 0; (len = in.read(buff)) > 0; ) {
|
||||
bo.write(buff, 0, len);
|
||||
}
|
||||
return bo.toByteArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String unzipLibrary(InputStream inputStream, String name) {
|
||||
try {
|
||||
if (libDir == null) {
|
||||
libDir = new File(System.getProperty("java.io.tmpdir"), "yjscontract_" + System.currentTimeMillis());
|
||||
libDir.mkdirs();
|
||||
}
|
||||
File f = new File(libDir, name);
|
||||
f.createNewFile();
|
||||
toLoad.add(f.getAbsolutePath());
|
||||
FileOutputStream fout = new FileOutputStream(f);
|
||||
byte[] buff = new byte[1024 * 100];
|
||||
for (int k = 0; (k = inputStream.read(buff)) > 0; ) {
|
||||
fout.write(buff, 0, k);
|
||||
}
|
||||
fout.close();
|
||||
return f.getAbsolutePath();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "/dev/null";
|
||||
}
|
||||
|
||||
private void addDirToPath(String s) {
|
||||
try {
|
||||
System.out.println("[YJSClassloader] addtopath:" + s);
|
||||
Field field = ClassLoader.class.getDeclaredField("sys_paths");
|
||||
field.setAccessible(true);
|
||||
String[] path = (String[]) field.get(null);
|
||||
String[] temp = new String[path.length + 1];
|
||||
System.arraycopy(path, 0, temp, 0, path.length);
|
||||
temp[path.length] = s;
|
||||
field.set(null, temp);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadLibraries() {
|
||||
if (libDir != null)
|
||||
addDirToPath(libDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
11
src/main/java/org/bdware/sc/engine/YJSFilter.java
Normal file
11
src/main/java/org/bdware/sc/engine/YJSFilter.java
Normal file
@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.ClassFilter;
|
||||
|
||||
public class YJSFilter implements ClassFilter {
|
||||
@Override
|
||||
public boolean exposeToScripts(String arg0) {
|
||||
return true;
|
||||
//return arg0.compareTo("java.io.File") != 0;
|
||||
}
|
||||
}
|
173
src/main/java/org/bdware/sc/engine/gbk.yjs
Normal file
173
src/main/java/org/bdware/sc/engine/gbk.yjs
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,34 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.ConfidentialContractUtil;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
public class ConfidentialHandler implements AnnotationHook {
|
||||
private final FunctionNode fun;
|
||||
|
||||
public ConfidentialHandler(FunctionNode fun) {
|
||||
this.fun = fun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
try {
|
||||
DesktopEngine desktopEngine = (DesktopEngine) engine;
|
||||
ConfidentialContractUtil.copyTemplateToDestination(input);
|
||||
ScriptObjectMirror globalVars = (ScriptObjectMirror) desktopEngine.get("Global");
|
||||
ConfidentialContractUtil.dumpScriptAndStates(
|
||||
desktopEngine.engine, fun, input, globalVars);
|
||||
// run in SGX instead of Nashorn if function has @Confidential annotation
|
||||
ret = ConfidentialContractUtil.executeConfidentialContract(input);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
86
src/main/java/org/bdware/sc/engine/hook/HomoVisitor.java
Normal file
86
src/main/java/org/bdware/sc/engine/hook/HomoVisitor.java
Normal file
@ -0,0 +1,86 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.bdware.mockjava.JsonVisitor;
|
||||
import org.paillier.PaillierCipher;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
public class HomoVisitor extends JsonVisitor {
|
||||
public static RSAPublicKey publicKey;
|
||||
JsonElement root;
|
||||
public static RSAPrivateKey privateKey;
|
||||
|
||||
public HomoVisitor(JsonElement ret) {
|
||||
root = ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitObject(JsonObject homoConfig) {
|
||||
if (root.isJsonObject()) {
|
||||
JsonObject jo = root.getAsJsonObject();
|
||||
for (String key : homoConfig.keySet()) {
|
||||
if (jo.has(key)) {
|
||||
HomoVisitor visitor = new HomoVisitor(jo.get(key));
|
||||
visitor.visit(homoConfig.get(key));
|
||||
jo.add(key, visitor.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitJsonArray(JsonArray ele) {
|
||||
if (root.isJsonArray()) {
|
||||
JsonArray array = root.getAsJsonArray();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
HomoVisitor visitor = new HomoVisitor((array.get(i)));
|
||||
visitor.visit(ele.get(0));
|
||||
array.set(i, visitor.get());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonElement get() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitPrimitive(JsonPrimitive primitive) {
|
||||
if (primitive.isString()) {
|
||||
String method = primitive.getAsString();
|
||||
try {
|
||||
String result = "";
|
||||
if (method.equals("@encrypt")) {
|
||||
BigInteger i = handleRoot(root.getAsString());
|
||||
result = PaillierCipher.encrypt(i, publicKey);
|
||||
} else if (method.equals("@decrypt")) {
|
||||
BigInteger i = PaillierCipher.decrypt(root.getAsString(), privateKey);
|
||||
result = String.valueOf(i);
|
||||
} else {
|
||||
result = root.getAsString();
|
||||
}
|
||||
System.out.println(result);
|
||||
root = new JsonPrimitive(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private BigInteger handleRoot(String data) {
|
||||
double d = Double.parseDouble(data);
|
||||
long l = (long) d;
|
||||
return BigInteger.valueOf(l);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.paillier.PaillierKeyPair;
|
||||
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
|
||||
public class HomomorphicDecryptHandler implements AnnotationHook {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ObjToJsonHandler.class);
|
||||
|
||||
private final FunctionNode fun;
|
||||
|
||||
public HomomorphicDecryptHandler(FunctionNode fun) {
|
||||
this.fun = fun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
try {
|
||||
// GetHomArgs args =
|
||||
// new GetHomArgs(
|
||||
// input.getRequester(), this.fun.getSecretID().replaceAll("\"", ""));
|
||||
// String arg = JsonUtil.toJson(args);
|
||||
JsonElement homoDecryptConf = this.fun.getHomoDecryptConf();
|
||||
if (null != homoDecryptConf && !homoDecryptConf.isJsonNull()) {
|
||||
String res =
|
||||
JavaScriptEntry.executeContract(
|
||||
"keyManager_1",
|
||||
"getPrivKey",
|
||||
this.fun.getSecretID().replaceAll("\"", ""));
|
||||
LOGGER.info("HomomorphicDecryptHandler--------------------------------1: " + res);
|
||||
ContractResult results = JsonUtil.fromJson(res, ContractResult.class);
|
||||
String privKeyStr = results.result.getAsString();
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------2: " + privKeyStr);
|
||||
RSAPrivateKey privkey = (RSAPrivateKey) PaillierKeyPair.pemToPrivateKey(privKeyStr);
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------3: " + privkey);
|
||||
HomoVisitor.privateKey = privkey;
|
||||
ret = getDecryptResult(homoDecryptConf, JsonUtil.parseObject(ret));
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
ret = new JsonObject();
|
||||
}
|
||||
return ret;
|
||||
// return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Object getDecryptResult(JsonElement homoDecryptConf, JsonElement data) {
|
||||
if (null == homoDecryptConf) {
|
||||
return data;
|
||||
}
|
||||
HomoVisitor visitor = new HomoVisitor(data);
|
||||
visitor.visit(homoDecryptConf);
|
||||
|
||||
JsonElement root = visitor.get();
|
||||
LOGGER.info("HomoRetInvoke: " + root);
|
||||
return root;
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.paillier.PaillierKeyPair;
|
||||
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
public class HomomorphicEncryptHandler implements AnnotationHook {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ObjToJsonHandler.class);
|
||||
|
||||
private final FunctionNode fun;
|
||||
|
||||
public HomomorphicEncryptHandler(FunctionNode fun) {
|
||||
this.fun = fun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
try {
|
||||
LOGGER.info(
|
||||
"HomomorphicEncryptHandler--------------------------------1: "
|
||||
+ input.getRequester());
|
||||
LOGGER.info(
|
||||
"HomomorphicEncryptHandler--------------------------------2: "
|
||||
+ this.fun.getSecretID());
|
||||
JsonElement response = (JsonElement) ret;
|
||||
JsonElement homoEncryptConf = this.fun.getHomoEncryptConf();
|
||||
if (homoEncryptConf != null && !homoEncryptConf.isJsonNull()) {
|
||||
String res =
|
||||
JavaScriptEntry.executeContract(
|
||||
"keyManager_1",
|
||||
"getPubKey",
|
||||
this.fun.getSecretID().replaceAll("\"", ""));
|
||||
// String res =
|
||||
// JavaScriptEntry.executeContract(
|
||||
// this.fun.getKeyManagerID(),
|
||||
// "getPubKey",
|
||||
// this.fun.getSecretID().replaceAll("\"", ""));
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------4: " + res);
|
||||
ContractResult results = JsonUtil.fromJson(res, ContractResult.class);
|
||||
String pubKeyStr = results.result.getAsString();
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------5: " + pubKeyStr);
|
||||
HomoVisitor.publicKey = (RSAPublicKey) PaillierKeyPair.pemToPublicKey(pubKeyStr);
|
||||
// if (homoEncryptConf.getAsJsonPrimitive().isString())
|
||||
// homoEncryptConf = JsonParser.parseString(homoEncryptConf.getAsString());
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------6: " + homoEncryptConf);
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------7: " + ret);
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------8: " + ret.toString());
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------9: " + JsonUtil.toJson(ret));
|
||||
ret = getEncryptResult(homoEncryptConf, response);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
ret = new JsonObject();
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Object getEncryptResult(JsonElement homoEncryptConf, JsonElement data) {
|
||||
// if (null == homoEncryptConf || homoEncryptConf.getAsString().isEmpty()) {
|
||||
// return data;
|
||||
// }
|
||||
if (null == homoEncryptConf) {
|
||||
return data;
|
||||
}
|
||||
HomoVisitor visitor = new HomoVisitor(data);
|
||||
visitor.visit(homoEncryptConf);
|
||||
|
||||
JsonElement root = visitor.get();
|
||||
System.out.println("HomoRetInvoke: " + root);
|
||||
LOGGER.info("HomoRetInvoke: " + root);
|
||||
return root;
|
||||
}
|
||||
}
|
59
src/main/java/org/bdware/sc/engine/hook/MaskHandler.java
Normal file
59
src/main/java/org/bdware/sc/engine/hook/MaskHandler.java
Normal file
@ -0,0 +1,59 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.bean.ProjectConfig;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
|
||||
public class MaskHandler implements AnnotationHook {
|
||||
private static final Logger LOGGER = LogManager.getLogger(MaskHandler.class);
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine Engine, Object ret) {
|
||||
try {
|
||||
DesktopEngine desktopEngine = (DesktopEngine) Engine;
|
||||
ProjectConfig projectConfig = desktopEngine.getProjectConfig();
|
||||
JsonElement maskConf = projectConfig.getMask(input.getAction());
|
||||
LOGGER.info("execute maskConf: " + maskConf);
|
||||
if (null != maskConf) {
|
||||
String s1 = ret.toString();
|
||||
//budeijin
|
||||
//"{\"count\":1}"
|
||||
//{"count":1}
|
||||
//System.out.println(s1);
|
||||
s1 = s1.replace("\\", "");
|
||||
s1 = s1.substring(1, s1.length() - 1);
|
||||
//System.out.println(s1);
|
||||
//System.out.println(JsonParser.parseString(s1));
|
||||
MaskVisitor visitor = new MaskVisitor(JsonParser.parseString(s1));
|
||||
visitor.visit(maskConf);
|
||||
ret = visitor.get();
|
||||
System.out.println(maskConf);
|
||||
if (null != ret) {
|
||||
return ret;
|
||||
}
|
||||
ret = JsonParser.parseString("");
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getMaskResult(JsonElement maskConfigInvoke, JsonElement data) {
|
||||
if (null == maskConfigInvoke || maskConfigInvoke.getAsString().isEmpty()) {
|
||||
return data;
|
||||
}
|
||||
MaskVisitor visitor = new MaskVisitor(data);
|
||||
visitor.visit(maskConfigInvoke);
|
||||
JsonElement root = visitor.get();
|
||||
LOGGER.info("MaskRetInvoke: " + root);
|
||||
return root;
|
||||
}
|
||||
}
|
97
src/main/java/org/bdware/sc/engine/hook/MaskVisitor.java
Normal file
97
src/main/java/org/bdware/sc/engine/hook/MaskVisitor.java
Normal file
@ -0,0 +1,97 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.cryptology.AESEncryptionImpl;
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.cryptology.FormatPreservingEncryptionImpl;
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.differentialPrivacy.EpsilonDifferentialPrivacyImpl;
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.irreversibleInterference.MD5EncryptionImpl;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.bdware.mockjava.JsonVisitor;
|
||||
|
||||
public class MaskVisitor extends JsonVisitor {
|
||||
JsonElement root;
|
||||
|
||||
public MaskVisitor(JsonElement ret) {
|
||||
root = ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitObject(JsonObject mask) {
|
||||
if (root.isJsonObject()) {
|
||||
JsonObject jo = root.getAsJsonObject();
|
||||
for (String key : mask.keySet()) {
|
||||
if (jo.has(key)) {
|
||||
//TODO
|
||||
MaskVisitor visitor = new MaskVisitor(jo.get(key));
|
||||
visitor.visit(mask.get(key));
|
||||
jo.add(key, visitor.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitJsonArray(JsonArray ele) {
|
||||
if (root.isJsonArray()) {
|
||||
JsonArray array = root.getAsJsonArray();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
MaskVisitor visitor = new MaskVisitor(array.get(i));
|
||||
visitor.visit(ele.get(0));
|
||||
array.set(i, visitor.get());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonElement get() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public JsonVisitor visitPrimitive(JsonPrimitive primitive) {
|
||||
//
|
||||
if (primitive.isString()) {
|
||||
String method = primitive.getAsString();
|
||||
try {
|
||||
String result = "";
|
||||
//md5不需要参数
|
||||
if (method.equals("md5")) {
|
||||
MD5EncryptionImpl masker = new MD5EncryptionImpl();
|
||||
result = masker.execute(root.getAsString());
|
||||
} else if (method.equals("aes")) {
|
||||
AESEncryptionImpl masker = new AESEncryptionImpl();
|
||||
result = masker.execute(root.getAsString());
|
||||
} else if (method.equals("fpe")) {
|
||||
FormatPreservingEncryptionImpl masker = new FormatPreservingEncryptionImpl();
|
||||
result = masker.execute(root.getAsString());
|
||||
}
|
||||
//edp需要精度的参数
|
||||
else if (method.equals("edp")) {
|
||||
EpsilonDifferentialPrivacyImpl masker = new EpsilonDifferentialPrivacyImpl();
|
||||
double epsilon = 1;
|
||||
|
||||
result = "" + masker.maskOne(root.getAsDouble(), epsilon);
|
||||
} else {
|
||||
result = root.getAsString();
|
||||
}
|
||||
System.out.println(result);
|
||||
root = new JsonPrimitive(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//String result = masker.execute(primitive.toString());
|
||||
//System.out.println(result);
|
||||
|
||||
//root = new JsonPrimitive(root.getAsString().substring(0, 2));
|
||||
//https://github.com/guohf/DataX-Masking
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import org.bdware.mockjava.MockUtil;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.bean.ProjectConfig;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
|
||||
public class MockTemplateHandler implements AnnotationHook {
|
||||
@Override
|
||||
public Object handle(ContractRequest request, JSEngine engine, Object ret) {
|
||||
if (request.fromDebug()) {
|
||||
System.out.println(request.getAction());
|
||||
DesktopEngine desktopEngine = (DesktopEngine) engine;
|
||||
ProjectConfig projectConfig = desktopEngine.getProjectConfig();
|
||||
String template = projectConfig.getMock(request.getAction());
|
||||
if (template != null && template.length() > 0) {
|
||||
System.out.println(template);
|
||||
MockUtil Mock = new MockUtil();
|
||||
return Mock.mock(template).toString();
|
||||
}
|
||||
else return ret; //When mock config is null defined just ignore.
|
||||
} else return ret;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.JSONTool;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
public class ObjToJsonHandler implements AnnotationHook {
|
||||
// private static final Logger LOGGER = LogManager.getLogger(ObjToJsonHandler.class);
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine desktopEngine, Object ret) {
|
||||
JsonElement je;
|
||||
if (ret == null) {
|
||||
je = JsonNull.INSTANCE;
|
||||
} else if (ret instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror ret2 = (ScriptObjectMirror) ret;
|
||||
// LOGGER.debug("[before parse to json]" + ret2);
|
||||
je = JSONTool.copy(ret2);
|
||||
} else if (ret instanceof jdk.nashorn.api.scripting.ScriptObjectMirror) {
|
||||
jdk.nashorn.api.scripting.ScriptObjectMirror ret2 =
|
||||
(jdk.nashorn.api.scripting.ScriptObjectMirror) ret;
|
||||
// LOGGER.debug("[before parse to json]" + ret2);
|
||||
je = JSONTool.copy(ret2);
|
||||
} else if (ret instanceof Number) {
|
||||
je = new JsonPrimitive((Number) ret);
|
||||
} else if (ret instanceof Character) {
|
||||
je = new JsonPrimitive((Character) ret);
|
||||
} else if (ret instanceof Boolean) {
|
||||
je = new JsonPrimitive((Boolean) ret);
|
||||
} else if (ret instanceof String) {
|
||||
je = new JsonPrimitive((String) ret);
|
||||
} else {
|
||||
je = new JsonPrimitive(ret.toString());
|
||||
}
|
||||
return je;
|
||||
}
|
||||
}
|
67
src/main/java/org/bdware/sc/engine/hook/ReadMeHandler.java
Normal file
67
src/main/java/org/bdware/sc/engine/hook/ReadMeHandler.java
Normal file
@ -0,0 +1,67 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.commonmark.node.FencedCodeBlock;
|
||||
import org.commonmark.node.Heading;
|
||||
import org.commonmark.node.Node;
|
||||
import org.commonmark.node.Text;
|
||||
import org.commonmark.parser.Parser;
|
||||
|
||||
public class ReadMeHandler implements AnnotationHook {
|
||||
String getReadMeData(DesktopEngine desktopEngine, ContractRequest c) {
|
||||
String fileReadme =
|
||||
desktopEngine
|
||||
.getResources()
|
||||
.loadAsString("/assets/README.md"); // is "/README.md" not"./README.md"!!!!
|
||||
// System.out.println("fileReadme:" + fileReadme);
|
||||
if (null == fileReadme) {
|
||||
return "项目目录下无预览文档";
|
||||
} else {
|
||||
String result = "未能返回调试调用结果";
|
||||
String targetFunction = c.getAction();
|
||||
try {
|
||||
Parser parser = Parser.builder().build();
|
||||
Node document = parser.parse(fileReadme);
|
||||
Node visitor = document.getFirstChild();
|
||||
while (visitor != null) {
|
||||
if (visitor instanceof Heading) {
|
||||
if (((Heading) visitor).getLevel() == 2) {
|
||||
if (((Text) (visitor.getFirstChild()))
|
||||
.getLiteral()
|
||||
.equals(targetFunction)) {
|
||||
FencedCodeBlock blockResult =
|
||||
(FencedCodeBlock)
|
||||
(visitor.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext());
|
||||
result = blockResult.getLiteral();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
visitor = visitor.getNext();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
DesktopEngine desktopEngine = (DesktopEngine) engine;
|
||||
if (input.fromDebug() && (ret == null || ret.equals("emptyMock"))) {
|
||||
ret = getReadMeData(desktopEngine, input);
|
||||
System.out.println(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
12
src/main/java/org/bdware/sc/engine/setArgs/GetHomArgs.java
Normal file
12
src/main/java/org/bdware/sc/engine/setArgs/GetHomArgs.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.engine.setArgs;
|
||||
|
||||
public class GetHomArgs {
|
||||
public String secretID;
|
||||
|
||||
public GetHomArgs() {
|
||||
}
|
||||
|
||||
public GetHomArgs(String secretID) {
|
||||
this.secretID = secretID;
|
||||
}
|
||||
}
|
298
src/main/java/org/bdware/sc/handler/ContractHandler.java
Normal file
298
src/main/java/org/bdware/sc/handler/ContractHandler.java
Normal file
@ -0,0 +1,298 @@
|
||||
package org.bdware.sc.handler;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.bean.Contract;
|
||||
import org.bdware.sc.conn.Description;
|
||||
import org.bdware.sc.conn.MsgHandler;
|
||||
import org.bdware.sc.conn.ResultCallback;
|
||||
import org.bdware.sc.conn.ServiceServer;
|
||||
import org.bdware.sc.get.GetMessage;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContractHandler extends MsgHandler implements Runnable {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ContractHandler.class);
|
||||
ContractProcess cs;
|
||||
String identifier = "null";
|
||||
|
||||
public ContractHandler(ContractProcess cs) {
|
||||
this.cs = cs;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("ContractHandler: exit in 2 seconds!");
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@Description("start sync mech")
|
||||
public void startSync(GetMessage msg, ResultCallback cb) {
|
||||
cs.startSync();
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("stop sync mech")
|
||||
public void stopSync(GetMessage msg, ResultCallback cb) {
|
||||
cs.stopSync();
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("set ContractRecord file name")
|
||||
public void setCRFile(GetMessage msg, ResultCallback cb) {
|
||||
cs.setCRFile(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("set contractDir")
|
||||
public void setDir(GetMessage msg, ResultCallback cb) {
|
||||
System.out.println("ContractHandler setDir");
|
||||
cs.setDir(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("getDebug")
|
||||
public void getDebug(GetMessage msg, ResultCallback cb) {
|
||||
LOGGER.debug("getDebug");
|
||||
cb.onResult(JsonUtil.toJson(cs.isDebug()));
|
||||
}
|
||||
|
||||
@Description("clearSyncFiles")
|
||||
public void clearSyncFiles(GetMessage msg, ResultCallback cb) {
|
||||
cs.clearSyncFiles(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("changeDumpPeriod")
|
||||
public void changeDumpPeriod(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.changeDumpPeriod(msg.arg));
|
||||
}
|
||||
|
||||
@Description("getDumpPeriod")
|
||||
public void getDumpPeriod(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getDumpPeriod());
|
||||
}
|
||||
|
||||
@Description("getCachedTransRecords")
|
||||
public void getCachedTransRecords(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getCachedTransRecords(msg.arg));
|
||||
}
|
||||
|
||||
@Description("start auto dump")
|
||||
public void startAutoDump(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.startAutoDump());
|
||||
}
|
||||
|
||||
@Description("register manager port")
|
||||
public void registerMangerPort(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.registerMangerPort(msg.arg));
|
||||
}
|
||||
|
||||
@Description("set current ContractBundle")
|
||||
public void setContractBundle(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.setContractBundle(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description("get current contract name")
|
||||
public void getContractName(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getContractName());
|
||||
}
|
||||
|
||||
@Description("set current Contract")
|
||||
public void setContract(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.setContract(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description(value = "execute contract")
|
||||
public void executeContract(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.executeContract(msg.arg));
|
||||
}
|
||||
|
||||
@Description("set DesktopPermission")
|
||||
public void setDesktopPermission(GetMessage msg, ResultCallback cb) {
|
||||
String result = cs.setDesktopPermission(msg.arg);
|
||||
cb.onResult(result);
|
||||
}
|
||||
|
||||
@Description("change debug Flag")
|
||||
public void changeDebugFlag(GetMessage msg, ResultCallback cb) {
|
||||
String result = cs.changeDebugFlag(Boolean.valueOf(msg.arg));
|
||||
cb.onResult(result);
|
||||
}
|
||||
|
||||
@Description("get functionEvaluates ")
|
||||
public void functionEvaluates(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.evaluatesAnalysis(msg.arg));
|
||||
}
|
||||
|
||||
@Description("get memory set")
|
||||
public void getMemorySet(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getMemorySet());
|
||||
}
|
||||
|
||||
@Description("get logType ")
|
||||
public void getLogType(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getLogType(msg.arg));
|
||||
}
|
||||
|
||||
@Description("exit Contract!")
|
||||
public void suicide(GetMessage msg, ResultCallback cb) {
|
||||
Map<String, Object> ret = new HashMap<>();
|
||||
ret.put("status", "success");
|
||||
cs.beforeSuicide();
|
||||
if (cs.checkSub()) {
|
||||
ret.put("cleanSub", true);
|
||||
}
|
||||
ServiceServer.executor.execute(this);
|
||||
cb.onResult(JsonUtil.toJson(ret));
|
||||
}
|
||||
|
||||
@Description("check alive")
|
||||
public void ping(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult("pong");
|
||||
}
|
||||
|
||||
@Description("dump contract process memory")
|
||||
public void getMemoryDump(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getMemoryDump(msg.arg));
|
||||
}
|
||||
|
||||
@Description("get memory usage")
|
||||
public void getStorage(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getStorage());
|
||||
}
|
||||
|
||||
@Description("redo by local trans record")
|
||||
public void redo(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.redo(msg.arg));
|
||||
}
|
||||
|
||||
@Description("load dumped memory")
|
||||
public void loadMemory(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.loadMemoryDump(msg.arg));
|
||||
}
|
||||
|
||||
@Description("setDBInfo, the db is used to store local logs")
|
||||
public void setDBInfo(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.setDBInfo(msg.arg));
|
||||
}
|
||||
|
||||
@Description("getUsedMemory")
|
||||
public void getUsedMemory(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getUsedMemory("") + "");
|
||||
}
|
||||
|
||||
@Description("showPermission")
|
||||
public void showPermission(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.showPermission());
|
||||
}
|
||||
|
||||
@Description("is signature required?")
|
||||
public void isSigRequired(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.isSigRequired() + "");
|
||||
}
|
||||
|
||||
@Description("Get Declared Events")
|
||||
public void getDeclaredEvents(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getDeclaredEvents());
|
||||
}
|
||||
|
||||
@Description("Get Contract Annotations")
|
||||
public void getAnnotations(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getAnnotations());
|
||||
}
|
||||
|
||||
@Description("Get Exported Functions")
|
||||
public void getExportedFunctions(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getExportedFunctions());
|
||||
}
|
||||
|
||||
@Description("Whether current process is contract process, always cmi")
|
||||
public void isContractProcess(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.cmi);
|
||||
}
|
||||
|
||||
@Description("get contract")
|
||||
public void getContract(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getContract());
|
||||
}
|
||||
|
||||
@Description("setPID")
|
||||
public void setPID(GetMessage msg, ResultCallback cb) {
|
||||
cs.setPID(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("setProjectConfig")
|
||||
public void setProjectConfig(GetMessage msg, ResultCallback cb) {
|
||||
LOGGER.debug("ContractHandler: " + msg.arg);
|
||||
cs.setProjectConfig(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("getPID")
|
||||
public void getPID(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getPID());
|
||||
}
|
||||
|
||||
@Description("requestLogSize")
|
||||
public void getLogSize(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.logSize() + "");
|
||||
}
|
||||
|
||||
@Description("request Log")
|
||||
public void requestLog(GetMessage msg, ResultCallback cb) {
|
||||
String[] data = msg.arg.split(",");
|
||||
cb.onResult(cs.requestLog(Long.parseLong(data[0]), Integer.parseInt(data[1])));
|
||||
}
|
||||
|
||||
@Description("request LastLog")
|
||||
public void requestLastLog(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.requestLast(Integer.parseInt(msg.arg)));
|
||||
}
|
||||
|
||||
@Description("setIdentifier")
|
||||
public void setIdentifier(GetMessage msg, ResultCallback cb) {
|
||||
identifier = msg.arg;
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("getIdentifier")
|
||||
public void getIdentifier(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(identifier);
|
||||
}
|
||||
|
||||
@Description("getControlFlow")
|
||||
public void getControlFlow(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getControlFlow(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description("getStateful")
|
||||
public void getStateful(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getStateful());
|
||||
}
|
||||
|
||||
@Description("parseYpkPermissions")
|
||||
public void parseYpkPermissions(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.parseYpkPermissions(msg.arg));
|
||||
}
|
||||
|
||||
@Description("staticVerify")
|
||||
public void staticVerify(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.staticVerify(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description("getDependentContracts")
|
||||
public void getDependentContracts(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getDependentContracts());
|
||||
}
|
||||
|
||||
|
||||
}
|
13
src/main/java/org/bdware/sc/handler/Exitor.java
Normal file
13
src/main/java/org/bdware/sc/handler/Exitor.java
Normal file
@ -0,0 +1,13 @@
|
||||
package org.bdware.sc.handler;
|
||||
|
||||
public class Exitor implements Runnable {
|
||||
public void run() {
|
||||
System.out.println("ContractHandler: exit in 2 seconds!");
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
21
src/main/java/org/bdware/sc/memory/JSEDump.java
Normal file
21
src/main/java/org/bdware/sc/memory/JSEDump.java
Normal file
@ -0,0 +1,21 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSEDump implements Serializable {
|
||||
long invokeID;
|
||||
long ranSeed;
|
||||
int numsOfCopies;
|
||||
|
||||
public JSEDump(long id,long ra,int nums){
|
||||
invokeID = id;
|
||||
ranSeed = ra;
|
||||
numsOfCopies = nums;
|
||||
}
|
||||
|
||||
public void printContent(){
|
||||
System.out.println("invokeID=" + invokeID);
|
||||
System.out.println("ranSeed=" + ranSeed);
|
||||
System.out.println("numsOfCopies=" + numsOfCopies);
|
||||
}
|
||||
}
|
40
src/main/java/org/bdware/sc/memory/MOType.java
Normal file
40
src/main/java/org/bdware/sc/memory/MOType.java
Normal file
@ -0,0 +1,40 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import jdk.internal.dynalink.beans.StaticClass;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
public enum MOType {
|
||||
String(true), Int(true), Double(true), Boolean(true),JSObject(false), JSArray(false), JavaObject(false), Method(false),
|
||||
Undefined(true), JSFunction(false),JSStatic(false);
|
||||
|
||||
private boolean isPrimitive;
|
||||
|
||||
MOType(boolean isPrimitive) {
|
||||
this.isPrimitive = (isPrimitive);
|
||||
}
|
||||
|
||||
public static MOType getType(Object obj) {
|
||||
if (obj == null)
|
||||
return Undefined;
|
||||
if (obj instanceof Integer) {
|
||||
return Int;
|
||||
} else if (obj instanceof Double) {
|
||||
return Double;
|
||||
} else if (obj instanceof String) {
|
||||
return String;
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
// ------
|
||||
return JSObject;
|
||||
}else if(obj instanceof StaticClass) {
|
||||
return JSStatic;
|
||||
}else if(obj instanceof Boolean){
|
||||
return Boolean;
|
||||
}
|
||||
return JSObject;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return isPrimitive;
|
||||
}
|
||||
|
||||
}
|
12
src/main/java/org/bdware/sc/memory/MemoryArrayObject.java
Normal file
12
src/main/java/org/bdware/sc/memory/MemoryArrayObject.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
public class MemoryArrayObject extends MemoryJSObject{
|
||||
|
||||
private static final long serialVersionUID = -5805776423219733634L;
|
||||
|
||||
public MemoryArrayObject(long id) {
|
||||
super(id);
|
||||
type = MOType.JSArray;
|
||||
}
|
||||
|
||||
}
|
231
src/main/java/org/bdware/sc/memory/MemoryDump.java
Normal file
231
src/main/java/org/bdware/sc/memory/MemoryDump.java
Normal file
@ -0,0 +1,231 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.Context;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class MemoryDump implements Serializable {
|
||||
transient long id;
|
||||
transient Map<Object, Long> allocated; //js对象,id
|
||||
|
||||
Map<Long, MemoryObject> objects; //id,memory对象
|
||||
JSEDump jseDump;
|
||||
|
||||
transient Map<Long, Object> recreate;
|
||||
|
||||
public MemoryDump() {
|
||||
objects = new HashMap<>();
|
||||
allocated = new HashMap<>();
|
||||
id = 0;
|
||||
getRoot();
|
||||
}
|
||||
|
||||
public static MemoryDump loadFromStr(String memDump) {
|
||||
JsonElement jo = new com.google.gson.JsonParser().parse(memDump);
|
||||
// JsonElement objs = jo.getAsJsonObject().get("objects");
|
||||
// JsonObject map = objs.getAsJsonObject();
|
||||
JsonObject map = jo.getAsJsonObject();
|
||||
MemoryDump ret = new MemoryDump();
|
||||
for (Entry<String, JsonElement> entry : map.entrySet()) {
|
||||
long id = Long.parseLong(entry.getKey());
|
||||
JsonObject obj = entry.getValue().getAsJsonObject();
|
||||
MOType type = MOType.valueOf(obj.get("type").getAsString());
|
||||
MemoryObject mo = null;
|
||||
|
||||
switch (type) {
|
||||
case JSObject:
|
||||
case JSArray:
|
||||
mo = JsonUtil.fromJson(obj, MemoryJSObject.class);
|
||||
break;
|
||||
case JSFunction:
|
||||
mo = JsonUtil.fromJson(obj, MemoryFunctionObject.class);
|
||||
break;
|
||||
case Int:
|
||||
mo = JsonUtil.fromJson(obj, MemoryObject.class);
|
||||
mo.data = Integer.parseInt(obj.get("data").getAsString());
|
||||
break;
|
||||
case Boolean:
|
||||
mo = JsonUtil.fromJson(obj, MemoryObject.class);
|
||||
mo.data = Boolean.parseBoolean(obj.get("data").getAsString());
|
||||
break;
|
||||
case String:
|
||||
case Double:
|
||||
mo = JsonUtil.fromJson(obj, MemoryObject.class);
|
||||
break;
|
||||
default:
|
||||
System.out.println("[MemoryDump] todo, missing type:" + type.toString());
|
||||
break;
|
||||
}
|
||||
ret.objects.put(id, mo);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Map<Long, MemoryObject> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
public void setObjects(Map<Long, MemoryObject> m) {
|
||||
this.objects = m;
|
||||
}
|
||||
|
||||
public MemoryJSObject getRoot() {
|
||||
if (objects.containsKey(0L))
|
||||
return (MemoryJSObject) objects.get(0L);
|
||||
else {
|
||||
MemoryJSObject jo = new MemoryJSObject(0);
|
||||
objects.put((long) 0, jo);
|
||||
return jo;
|
||||
}
|
||||
}
|
||||
|
||||
public long allocate(Object obj) {
|
||||
if (obj == null)
|
||||
return -1;
|
||||
|
||||
long currID;
|
||||
|
||||
id++;
|
||||
currID = id;
|
||||
if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) {
|
||||
/*
|
||||
String obj2 = "jdk.internal.dynalink.beans.StaticClass.class";
|
||||
if (allocated.containsKey(obj2))
|
||||
return allocated.get(obj2);
|
||||
allocated.put(obj2, currID);
|
||||
*/
|
||||
} else {
|
||||
if (allocated.containsKey(obj))
|
||||
return allocated.get(obj);
|
||||
allocated.put(obj, currID);
|
||||
}
|
||||
|
||||
|
||||
// 如果是对象
|
||||
if (obj.getClass() == ScriptObjectMirror.class) {
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) obj;
|
||||
if (som.isFunction()) {
|
||||
MemoryFunctionObject fo = new MemoryFunctionObject(currID);
|
||||
objects.put(currID, fo);
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
fo.addField(str, allocate(som.getMember(str)));
|
||||
}
|
||||
} else if (som.isArray()) {
|
||||
MemoryArrayObject ao = new MemoryArrayObject(currID);
|
||||
objects.put(currID, ao);
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
ao.addField(str, allocate(som.getMember(str)));
|
||||
}
|
||||
} else {
|
||||
MemoryJSObject jo = new MemoryJSObject(currID);
|
||||
objects.put(currID, jo);
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
jo.addField(str, allocate(som.getMember(str)));
|
||||
}
|
||||
}
|
||||
} else if (obj.getClass() == wrp.jdk.nashorn.internal.runtime.Undefined.class) {
|
||||
|
||||
} else if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) {
|
||||
//regard as String
|
||||
|
||||
// MemoryObject mo = new MemoryObject(currID);
|
||||
// mo.type = MOType.String;
|
||||
// mo.data = "jdk.internal.dynalink.beans.StaticClass";
|
||||
// objects.put(currID, mo);
|
||||
} else {
|
||||
MOType type = MOType.getType(obj);
|
||||
if (type.isPrimitive()) {
|
||||
MemoryObject mo = new MemoryObject(currID);
|
||||
mo.type = type;
|
||||
mo.data = obj;
|
||||
objects.put(currID, mo);
|
||||
} else
|
||||
System.out.println("[MemoryDump] Allocat MetType:" + obj.getClass() + " now id=" + currID);
|
||||
|
||||
}
|
||||
return currID;
|
||||
}
|
||||
|
||||
public Map<Long, Object> recreateObject() {
|
||||
recreate = new HashMap<>();
|
||||
fillRecreate();
|
||||
fillJO();
|
||||
return recreate;
|
||||
}
|
||||
|
||||
private void fillJO() {
|
||||
for (Long key : objects.keySet()) {
|
||||
MemoryObject mo = objects.get(key);
|
||||
if (mo == null)
|
||||
continue;
|
||||
|
||||
switch (mo.type) {
|
||||
case JSObject:
|
||||
case JSArray:
|
||||
MemoryJSObject mjo = (MemoryJSObject) mo;
|
||||
ScriptObjectMirror jo = (ScriptObjectMirror) recreate.get(key);
|
||||
for (String field : mjo.fields.keySet()) {
|
||||
Object temp = recreate.get(mjo.fields.get(field));
|
||||
|
||||
if (mjo.fields.get(field) >= 0) {
|
||||
if (field.length() > 0)
|
||||
jo.setMember(field, temp);
|
||||
else
|
||||
jo.setMember(" ", temp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void fillRecreate() {
|
||||
Context.setGlobal(JavaScriptEntry.getEngineGlobal());
|
||||
for (Long key : objects.keySet()) {
|
||||
Object obj = null;
|
||||
MemoryObject mo = objects.get(key);
|
||||
if (mo == null) {
|
||||
continue;
|
||||
}
|
||||
switch (mo.type) {
|
||||
case JSArray:
|
||||
obj = ScriptObjectMirror.wrap(Global.allocate(new int[0]), JavaScriptEntry.getEngineGlobal());
|
||||
break;
|
||||
case JSObject:
|
||||
obj = ScriptObjectMirror.wrap(new JO(PropertyMap.newMap()), JavaScriptEntry.getEngineGlobal());
|
||||
break;
|
||||
case JSFunction:
|
||||
break;
|
||||
case String:
|
||||
case Int:
|
||||
obj = mo.data;
|
||||
break;
|
||||
case Double:
|
||||
obj = Double.parseDouble(mo.data.toString());
|
||||
break;
|
||||
default:
|
||||
System.out.println("[MemoryDump] todo, missing type:" + mo.type.toString());
|
||||
break;
|
||||
}
|
||||
|
||||
recreate.put(key, obj);
|
||||
}
|
||||
}
|
||||
}
|
155
src/main/java/org/bdware/sc/memory/MemoryDumpUtil.java
Normal file
155
src/main/java/org/bdware/sc/memory/MemoryDumpUtil.java
Normal file
@ -0,0 +1,155 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptContext;
|
||||
import java.io.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class MemoryDumpUtil {
|
||||
public static final String STATELESS_MEMORY = "statelessContractMemory";
|
||||
public static AtomicInteger checkPointCounter; //用于common模式下的检查点计数
|
||||
NashornScriptEngine engine;
|
||||
String dumpContent;
|
||||
MemoryDump memoryDump = null;
|
||||
|
||||
public MemoryDumpUtil(NashornScriptEngine en) {
|
||||
this.engine = en;
|
||||
}
|
||||
|
||||
public static String getContentFromFile(String path) {
|
||||
File file = new File(path);
|
||||
ObjectInputStream reader;
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
GZIPInputStream gzin = new GZIPInputStream(fileout);
|
||||
reader = new ObjectInputStream(gzin);
|
||||
MemoryDump memoryDump = new MemoryDump();
|
||||
//memoryDump.objects = (Map<Long, MemoryObject>) reader.readObject();
|
||||
memoryDump = (MemoryDump) reader.readObject();
|
||||
reader.close();
|
||||
String ret = JsonUtil.toPrettyJson(memoryDump.objects);
|
||||
ret += ("<seperate>" + memoryDump.jseDump.invokeID + ";" + memoryDump.jseDump.ranSeed + ";" + memoryDump.jseDump.numsOfCopies + "");
|
||||
return ret;
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
public static String getContentFromFile2(String path) {
|
||||
File file = new File(path);
|
||||
ObjectInputStream reader;
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
reader = new ObjectInputStream(fileout);
|
||||
String ret = (String)reader.readObject();
|
||||
reader.close();
|
||||
return ret;
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
//stateful 表示合约是有/无状态合约
|
||||
public String dumpMemory(String path, boolean stateful) {
|
||||
synchronized (engine) {
|
||||
String ret;
|
||||
memoryDump = new MemoryDump();
|
||||
|
||||
if (stateful) {
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
for (String key : bindings.keySet()) {
|
||||
Object obj = bindings.get(key);
|
||||
long id = memoryDump.allocate(obj);
|
||||
root.addField(key, id);
|
||||
}
|
||||
memoryDump.jseDump = new JSEDump(JavaScriptEntry.invokeID, Long.parseLong(JavaScriptEntry.currentSyncUtil.contractID), JavaScriptEntry.numOfCopies);
|
||||
ret = JsonUtil.toPrettyJson(memoryDump.objects);
|
||||
} else { //无状态合约
|
||||
memoryDump.jseDump = new JSEDump(JavaScriptEntry.invokeID, Long.parseLong(JavaScriptEntry.currentSyncUtil.contractID), JavaScriptEntry.numOfCopies);
|
||||
memoryDump.objects.clear();
|
||||
ret = JsonUtil.toPrettyJson(memoryDump.objects);
|
||||
}
|
||||
|
||||
ret += "--seperate--";
|
||||
ret += (memoryDump.jseDump.invokeID + ";" + memoryDump.jseDump.ranSeed + ";" + memoryDump.jseDump.numsOfCopies);
|
||||
|
||||
if (path == null || path.equals("")) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
File mem = new File(path);
|
||||
File parent = mem.getParentFile();
|
||||
if (!parent.exists()) parent.mkdirs();
|
||||
ObjectOutputStream writer;
|
||||
try {
|
||||
FileOutputStream fileout = new FileOutputStream(mem);
|
||||
GZIPOutputStream out = new GZIPOutputStream(fileout);
|
||||
writer = new ObjectOutputStream(out);
|
||||
//writer.writeObject(memoryDump.objects);
|
||||
writer.writeObject(memoryDump);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
memoryDump = null;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public String dumpMemory(String path) {
|
||||
memoryDump = new MemoryDump();
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
System.out.println("[MemoryDumpUtil] bindings size=" + bindings.size());
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
for (String key : bindings.keySet()) {
|
||||
System.out.println("[MemoryDumpUtil] dumpMemory " + key);
|
||||
Object obj = bindings.get(key);
|
||||
long id = memoryDump.allocate(obj);
|
||||
root.addField(key, id);
|
||||
|
||||
System.out.println("[root addFiled] key=" + key + " id=" + id);
|
||||
}
|
||||
String ret = JsonUtil.toPrettyJson(memoryDump);
|
||||
dumpContent = ret;
|
||||
|
||||
if(path == null || path.equals("")) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
File mem = new File(path);
|
||||
File parent = mem.getParentFile();
|
||||
if (!parent.exists())
|
||||
parent.mkdirs();
|
||||
ObjectOutputStream writer;
|
||||
try {
|
||||
FileOutputStream fileout = new FileOutputStream(mem);
|
||||
writer = new ObjectOutputStream(fileout);
|
||||
writer.writeObject(dumpContent);
|
||||
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
memoryDump = null;
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
}
|
19
src/main/java/org/bdware/sc/memory/MemoryFunctionObject.java
Normal file
19
src/main/java/org/bdware/sc/memory/MemoryFunctionObject.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MemoryFunctionObject extends MemoryObject {
|
||||
private static final long serialVersionUID = 5169037078273981613L;
|
||||
Map<String, Long> fields;
|
||||
|
||||
public MemoryFunctionObject(long id) {
|
||||
super(id);
|
||||
fields = new HashMap<>();
|
||||
type = MOType.JSFunction;
|
||||
}
|
||||
|
||||
public void addField(String key, long id) {
|
||||
fields.put(key, id);
|
||||
}
|
||||
}
|
19
src/main/java/org/bdware/sc/memory/MemoryJSObject.java
Normal file
19
src/main/java/org/bdware/sc/memory/MemoryJSObject.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MemoryJSObject extends MemoryObject {
|
||||
private static final long serialVersionUID = -2290414347562477503L;
|
||||
LinkedHashMap<String, Long> fields;
|
||||
|
||||
public MemoryJSObject(long id) {
|
||||
super(id);
|
||||
fields = new LinkedHashMap<>();
|
||||
type = MOType.JSObject;
|
||||
}
|
||||
|
||||
public void addField(String key, long id) {
|
||||
fields.put(key, id);
|
||||
}
|
||||
}
|
21
src/main/java/org/bdware/sc/memory/MemoryObject.java
Normal file
21
src/main/java/org/bdware/sc/memory/MemoryObject.java
Normal file
@ -0,0 +1,21 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class MemoryObject implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7830175031856452056L;
|
||||
public long id;
|
||||
public MOType type;
|
||||
Object data;
|
||||
|
||||
public MemoryObject(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return JsonUtil.toJson(this);
|
||||
}
|
||||
}
|
160
src/main/java/org/bdware/sc/memory/MemoryRecoverUtil.java
Normal file
160
src/main/java/org/bdware/sc/memory/MemoryRecoverUtil.java
Normal file
@ -0,0 +1,160 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.boundry.Resources;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptContext;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class MemoryRecoverUtil {
|
||||
NashornScriptEngine engine;
|
||||
String loadContent;
|
||||
MemoryDump memoryDump = null;
|
||||
Resources resource;
|
||||
|
||||
public MemoryRecoverUtil(NashornScriptEngine en, Resources r) {
|
||||
this.engine = en;
|
||||
this.resource = r;
|
||||
}
|
||||
|
||||
//支持传入memory文件路径或者直接是memory的字符串
|
||||
public void loadMemory(String path, boolean stateful) {
|
||||
synchronized (engine) {
|
||||
File file = new File(path);
|
||||
try {
|
||||
if (file.exists()) {
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
GZIPInputStream gzin = new GZIPInputStream(fileout);
|
||||
ObjectInputStream reader = new ObjectInputStream(gzin);
|
||||
|
||||
// MemoryDump temp = new MemoryDump();
|
||||
// temp.objects = (Map<Long, MemoryObject>) reader.readObject();
|
||||
// String content = JsonUtil.toPrettyJson(temp);
|
||||
|
||||
MemoryDump temp = (MemoryDump) reader.readObject();
|
||||
String content = JsonUtil.toPrettyJson(temp.objects);
|
||||
temp.jseDump.printContent();
|
||||
long invokeID = temp.jseDump.invokeID;
|
||||
int copies = temp.jseDump.numsOfCopies;
|
||||
long formerInvokeID = JavaScriptEntry.invokeID;
|
||||
JavaScriptEntry.invokeID = invokeID;
|
||||
JavaScriptEntry.numOfCopies = copies;
|
||||
if (JavaScriptEntry.random == null) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(temp.jseDump.ranSeed);
|
||||
}
|
||||
if (formerInvokeID > invokeID) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(temp.jseDump.ranSeed);
|
||||
for (long i = 0; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
} else {
|
||||
for (long i = formerInvokeID; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
//memoryDump = MemoryDump.loadFromStr(content);
|
||||
if (stateful) {
|
||||
memoryDump = temp;
|
||||
}
|
||||
reader.close();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else { //直接传入的是字符串
|
||||
String[] strs = path.split("--seperate--");
|
||||
String content = strs[0];
|
||||
String jse = strs[1];
|
||||
System.out.println("MemoryRecover从字符串load:\n" + content + "\n" + jse);
|
||||
String strs2[] = jse.split(";");
|
||||
long invokeID = Long.parseLong(strs2[0]);
|
||||
int copies = Integer.parseInt(strs2[2]);
|
||||
long formerInvokeID = JavaScriptEntry.invokeID;
|
||||
String contractID = strs2[1];
|
||||
JavaScriptEntry.invokeID = invokeID;
|
||||
JavaScriptEntry.numOfCopies = copies;
|
||||
if (JavaScriptEntry.random == null) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(Integer.valueOf(contractID));
|
||||
}
|
||||
if (formerInvokeID > invokeID) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(Integer.valueOf(contractID));
|
||||
for (long i = 0; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
} else {
|
||||
for (long i = formerInvokeID; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
if (stateful) { //有状态合约
|
||||
memoryDump = MemoryDump.loadFromStr(content);
|
||||
}
|
||||
}
|
||||
|
||||
if (stateful) {
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
Map<Long, Object> objects = memoryDump.recreateObject();
|
||||
ScriptObjectMirror global = (ScriptObjectMirror) objects.get(0L);
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
for (Object key : global.keySet()) {
|
||||
if (global.get(key) != null) bindings.put((String) key, global.get(key));
|
||||
}
|
||||
}
|
||||
this.memoryDump = null;
|
||||
if (resource != null)
|
||||
((Invocable) engine).invokeFunction("defineProp", "Resources", resource);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void loadMemory(String path) {
|
||||
try {
|
||||
String memory;
|
||||
File mem = new File(path);
|
||||
FileInputStream fileout = new FileInputStream(mem);
|
||||
ObjectInputStream reader = new ObjectInputStream(fileout);
|
||||
loadContent = (String) reader.readObject();
|
||||
// System.out.println("[MemoryRecoverUtil] loadContent : \n" + loadContent);
|
||||
reader.close();
|
||||
memoryDump = MemoryDump.loadFromStr(loadContent);
|
||||
|
||||
|
||||
String ret = JsonUtil.toPrettyJson(memoryDump);
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
Map<Long, Object> objects = memoryDump.recreateObject();
|
||||
ScriptObjectMirror global = (ScriptObjectMirror) objects.get(0L);
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
for (Object key : global.keySet()) {
|
||||
if (global.get(key) != null)
|
||||
bindings.put((String) key, global.get(key));
|
||||
}
|
||||
this.memoryDump = null;
|
||||
if (resource != null)
|
||||
((Invocable) engine).invokeFunction("defineProp", "Resources", resource);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
181
src/main/java/org/bdware/sc/redo/TransRecordUtil.java
Normal file
181
src/main/java/org/bdware/sc/redo/TransRecordUtil.java
Normal file
@ -0,0 +1,181 @@
|
||||
package org.bdware.sc.redo;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.engine.SyncMechUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class TransRecordUtil {
|
||||
public static final int RESERVED = 20; //最近的多少次records内存也保存,如果一个节点距离集群当前的seq相差超过这个值,就不从本地恢复,让别的节点现场dump
|
||||
public static final int DUMP_PERIOD = 50; //每满50次记录,就记录一次全量状态,清一次trans记录
|
||||
private static final Logger LOGGER = LogManager.getLogger(TransRecordUtil.class);
|
||||
public Map<Integer, TransRecord> cacheTransRecords = new TreeMap<Integer, TransRecord>(); //TODO 认为其中records一定是seq连续的,否则可能有问题?
|
||||
//public PriorityQueue<TransRecord> transRecords = new PriorityQueue<TransRecord>();
|
||||
public TransRecord currentTransRecord;
|
||||
SyncMechUtil syncUtil;
|
||||
DesktopEngine engine;
|
||||
String fileName;
|
||||
|
||||
public TransRecordUtil(DesktopEngine en, SyncMechUtil sync) {
|
||||
this.engine = en;
|
||||
syncUtil = sync;
|
||||
}
|
||||
|
||||
public void setFileName(String path) {
|
||||
fileName = path;
|
||||
}
|
||||
|
||||
//每次事务开始时初始化
|
||||
public void startNext(String fun, String arg, int sequence) {
|
||||
//logger.debug("TransRecordUtil 开始记录事务");
|
||||
currentTransRecord = new TransRecord(fun, arg, sequence);
|
||||
}
|
||||
|
||||
public void startNext(String fun, String arg) {
|
||||
//logger.debug("TransRecordUtil 开始记录事务");
|
||||
currentTransRecord = new TransRecord(fun, arg);
|
||||
}
|
||||
|
||||
//每次事务结束时记录
|
||||
public synchronized void eachFinish() {
|
||||
//logger.debug("TransRecordUtil 记录完一个事务 \n" + currentTransRecord.toString());
|
||||
cacheTransRecords.put(currentTransRecord.seq, currentTransRecord);
|
||||
if (cacheTransRecords.size() == RESERVED) {
|
||||
int temp = 0;
|
||||
for (Integer i : cacheTransRecords.keySet()) {
|
||||
temp = i;
|
||||
break;
|
||||
}
|
||||
cacheTransRecords.remove(temp);
|
||||
}
|
||||
|
||||
appendTransFile(currentTransRecord); //执行前已经定序了,所以trans其实没必要定序
|
||||
}
|
||||
|
||||
//追加写入最后一个TransRecord
|
||||
public void appendTransFile(TransRecord record) {
|
||||
syncUtil.filedTrans.getAndIncrement();
|
||||
|
||||
File file = new File(syncUtil.transDir + "/" + fileName);
|
||||
File parent = file.getParentFile();
|
||||
if (parent.isDirectory() && !parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
pw.println(record.toString());
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//自动触发检查点
|
||||
if (syncUtil.filedTrans.get() == DUMP_PERIOD) {
|
||||
LOGGER.info("自动触发检查点 DUMP_PERIOD=" + DUMP_PERIOD);
|
||||
file = new File(syncUtil.memoryDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
file = new File(syncUtil.traceDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
file = new File(syncUtil.transDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
//sync文件删除第2,3行
|
||||
file = new File(syncUtil.syncDir + "/" + syncUtil.syncFileName);
|
||||
String firstLine = "";
|
||||
try {
|
||||
FileReader fr = new FileReader(file);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
firstLine = line;
|
||||
break;
|
||||
}
|
||||
br.close();
|
||||
fr.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
file.delete();
|
||||
file = new File(syncUtil.syncDir + "/" + syncUtil.syncFileName);
|
||||
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
pw.println(firstLine);
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
syncUtil.setStartFlag(true);
|
||||
}
|
||||
}
|
||||
|
||||
//record executeContract in current trans
|
||||
public void recordExecutes(String k, String v) {
|
||||
if (currentTransRecord != null) {
|
||||
currentTransRecord.executes.put(k, v);
|
||||
} else {
|
||||
LOGGER.info("[TransRecordUtil] recordExecutes error!");
|
||||
}
|
||||
}
|
||||
|
||||
public String getCachedTransRecords(int start) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
//先查看有没有第1个
|
||||
if (!cacheTransRecords.containsKey(start))
|
||||
return "";
|
||||
|
||||
synchronized (cacheTransRecords) {
|
||||
int temp = -1;
|
||||
int j = start - 1;//确保有从start开始的连续trans,j记录上一个i值
|
||||
for (Integer i : cacheTransRecords.keySet()) {
|
||||
if (i >= start) {
|
||||
if (i == (j + 1)) {
|
||||
str.append(cacheTransRecords.get(i).toString() + "\n");
|
||||
temp = Math.max(temp, i);
|
||||
j = i;
|
||||
} else {
|
||||
LOGGER.info("i=" + i + " j=" + j + " 不连续");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (temp != -1)
|
||||
str.append("==>>" + temp);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
}
|
100
src/main/java/org/bdware/sc/redo/TransRecoverUtil.java
Normal file
100
src/main/java/org/bdware/sc/redo/TransRecoverUtil.java
Normal file
@ -0,0 +1,100 @@
|
||||
package org.bdware.sc.redo;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TransRecoverUtil {
|
||||
private static final Logger LOGGER = LogManager.getLogger(TransRecoverUtil.class);
|
||||
public ArrayList<TransRecord> transRecords;
|
||||
public TransRecord curRecoverRecord;
|
||||
DesktopEngine engine;
|
||||
|
||||
public TransRecoverUtil(DesktopEngine en) {
|
||||
this.engine = en;
|
||||
transRecords = new ArrayList<TransRecord>();
|
||||
}
|
||||
|
||||
public void setTraceRecords(String fileName) {
|
||||
TransRecord cur_read = null;
|
||||
File file = new File(fileName);
|
||||
|
||||
try {
|
||||
FileReader fr = new FileReader(file);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
String line = "";
|
||||
String[] arrs = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] strs = line.split(";");
|
||||
String arg;
|
||||
if (strs.length < 5) { //调用记录参数为空
|
||||
arg = null;
|
||||
} else {
|
||||
arg = strs[4];
|
||||
}
|
||||
|
||||
if (strs[0].equals("===TransRecord===")) {
|
||||
if (cur_read != null) {
|
||||
transRecords.add(cur_read);
|
||||
System.out.println("恢复时加入 " + cur_read.toString());
|
||||
}
|
||||
if (strs[1].equals("true"))
|
||||
cur_read = new TransRecord(strs[3], arg, Integer.parseInt(strs[2]));
|
||||
else
|
||||
cur_read = new TransRecord(strs[3], arg);
|
||||
} else {
|
||||
cur_read.addExecutes(strs[0], strs[1]);
|
||||
}
|
||||
}
|
||||
if (cur_read != null) {
|
||||
transRecords.add(cur_read);
|
||||
System.out.println("恢复时加入 " + cur_read.toString());
|
||||
}
|
||||
br.close();
|
||||
fr.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void recoverFromTransRecord() {
|
||||
synchronized (engine) {
|
||||
engine.setRecovering(true);
|
||||
for (int i = 0; i < transRecords.size(); i++) {
|
||||
curRecoverRecord = transRecords.get(i);
|
||||
String funName = curRecoverRecord.getFuncName();
|
||||
String arg = curRecoverRecord.getArg();
|
||||
|
||||
ContractRequest ac = null;
|
||||
ac = new ContractRequest();
|
||||
ac.setAction(funName);
|
||||
ac.setArg(arg);
|
||||
ac.needSeq = curRecoverRecord.needSeq;
|
||||
if (ac.needSeq) {
|
||||
ac.seq = curRecoverRecord.seq;
|
||||
LOGGER.info("[TransRecordUtil] redo 重新执行事务 " + ac.seq);
|
||||
}
|
||||
System.out.println("[TransRecoverUtil] recover " + ac.needSeq + " " + ac.seq + " " + ac.getAction() + " " + ac.getArg());
|
||||
|
||||
ContractResult result = engine.executeContract(ac);
|
||||
|
||||
if (result.status != ContractResult.Status.Success) {
|
||||
System.out.println("[错误]" + result.status);
|
||||
}
|
||||
}
|
||||
engine.setRecovering(false);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
public void recoverFromATransRecord(TransRecord record) {
|
||||
|
||||
}
|
||||
}
|
24
src/main/java/org/bdware/sc/syncMech/EstimateUtil.java
Normal file
24
src/main/java/org/bdware/sc/syncMech/EstimateUtil.java
Normal file
@ -0,0 +1,24 @@
|
||||
package org.bdware.sc.syncMech;
|
||||
|
||||
public class EstimateUtil {
|
||||
public static final String DUMP_TIME = "dumpTime";
|
||||
public static final String DUMP_TIMES = "dumpTimes";
|
||||
long dumpTime; //用时
|
||||
long dumpTimes; //次数
|
||||
long dumpFile; //状态大小,dumpFile的次数也是dumpTimes
|
||||
|
||||
public static final String LOADMEMORY_TIME = "loadMemoryTime";
|
||||
public static final String LOADMEMORY_TIMES = "loadMemoryTimes";
|
||||
long loadMemoryTime;
|
||||
long loadMemoryTimes;
|
||||
|
||||
public static final String EXECUTE_TIME = "executeTime";
|
||||
public static final String EXECUTE_TIMES = "executeTimes";
|
||||
long executeTime;
|
||||
long executeTimes;
|
||||
|
||||
public static final String REDO_TRANS_FILE = "redoTransFile";
|
||||
public static final String REDO_TRANS_TIMES = "redoTransTimes";
|
||||
long redoTransFIle;
|
||||
long redoTransTimes;
|
||||
}
|
44
src/main/java/org/bdware/sc/syncMech/SyncRecord.java
Normal file
44
src/main/java/org/bdware/sc/syncMech/SyncRecord.java
Normal file
@ -0,0 +1,44 @@
|
||||
package org.bdware.sc.syncMech;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SyncRecord implements Serializable{
|
||||
SyncType type;
|
||||
String fileName; //eg:/memory/2020-...
|
||||
|
||||
public SyncRecord(SyncType t) {
|
||||
this.type = t;
|
||||
}
|
||||
|
||||
public SyncRecord(SyncType t,String str){
|
||||
type = t;
|
||||
fileName = str;
|
||||
}
|
||||
|
||||
public void setType(SyncType ty) {
|
||||
this.type = ty;
|
||||
}
|
||||
|
||||
public SyncType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setFileName(String file) {
|
||||
this.fileName = file;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append(type.toString() + ";" + fileName);
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public static SyncRecord loadFromString(String str){
|
||||
String[] strs = str.split(";");
|
||||
return new SyncRecord(SyncType.convert(strs[0]),strs[1]);
|
||||
}
|
||||
}
|
20
src/main/java/org/bdware/sc/syncMech/SyncType.java
Normal file
20
src/main/java/org/bdware/sc/syncMech/SyncType.java
Normal file
@ -0,0 +1,20 @@
|
||||
package org.bdware.sc.syncMech;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public enum SyncType implements Serializable{
|
||||
Memory, Trace, Trans;
|
||||
|
||||
public static SyncType convert(String str){
|
||||
switch (str){
|
||||
case "Memory":
|
||||
return Memory;
|
||||
case "Trace":
|
||||
return Trace;
|
||||
case "Trans":
|
||||
return Trans;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
7
src/main/java/org/bdware/sc/trace/JS.java
Normal file
7
src/main/java/org/bdware/sc/trace/JS.java
Normal file
@ -0,0 +1,7 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JS implements Serializable{
|
||||
|
||||
}
|
10
src/main/java/org/bdware/sc/trace/JSArray.java
Normal file
10
src/main/java/org/bdware/sc/trace/JSArray.java
Normal file
@ -0,0 +1,10 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSArray extends JSScript implements Serializable{
|
||||
|
||||
public JSArray(int id) {
|
||||
this.objID = id;
|
||||
}
|
||||
}
|
7
src/main/java/org/bdware/sc/trace/JSNull.java
Normal file
7
src/main/java/org/bdware/sc/trace/JSNull.java
Normal file
@ -0,0 +1,7 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSNull extends JS implements Serializable{
|
||||
|
||||
}
|
14
src/main/java/org/bdware/sc/trace/JSObject.java
Normal file
14
src/main/java/org/bdware/sc/trace/JSObject.java
Normal file
@ -0,0 +1,14 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/*
|
||||
* js中对象
|
||||
* ScriptObject JO
|
||||
*/
|
||||
public class JSObject extends JSScript implements Serializable{
|
||||
|
||||
public JSObject(int id) {
|
||||
this.objID = id;
|
||||
}
|
||||
}
|
11
src/main/java/org/bdware/sc/trace/JSScript.java
Normal file
11
src/main/java/org/bdware/sc/trace/JSScript.java
Normal file
@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSScript extends JS implements Serializable{
|
||||
int objID;
|
||||
|
||||
public int getObjID() {
|
||||
return this.objID;
|
||||
}
|
||||
}
|
7
src/main/java/org/bdware/sc/trace/JSUndifined.java
Normal file
7
src/main/java/org/bdware/sc/trace/JSUndifined.java
Normal file
@ -0,0 +1,7 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSUndifined extends JS implements Serializable{
|
||||
|
||||
}
|
77
src/main/java/org/bdware/sc/trace/MethodInvokePrinter.java
Normal file
77
src/main/java/org/bdware/sc/trace/MethodInvokePrinter.java
Normal file
@ -0,0 +1,77 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Set;
|
||||
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import wrp.jdk.nashorn.internal.runtime.TraceMethod;
|
||||
|
||||
public class MethodInvokePrinter implements TraceMethod {
|
||||
|
||||
PrintStream out;
|
||||
|
||||
public void printObject(final Object arg) {
|
||||
if (arg instanceof ScriptObject) {
|
||||
final ScriptObject object = (ScriptObject) arg;
|
||||
|
||||
boolean isFirst = true;
|
||||
final Set<Object> keySet = object.keySet();
|
||||
|
||||
if (keySet.isEmpty()) {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
} else {
|
||||
out.print("{ ");
|
||||
|
||||
for (final Object key : keySet) {
|
||||
if (!isFirst) {
|
||||
out.print(", ");
|
||||
}
|
||||
|
||||
out.print(key);
|
||||
out.print(":");
|
||||
|
||||
final Object value = object.get(key);
|
||||
|
||||
if (value instanceof ScriptObject) {
|
||||
out.print("...");
|
||||
} else {
|
||||
printObject(value);
|
||||
}
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
out.print(" }");
|
||||
}
|
||||
} else {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
}
|
||||
}
|
||||
|
||||
public void tracePrint(final String tag, int pc, String methodName, final Object[] args, final Object result) {
|
||||
// boolean isVoid = type().returnType() == void.class;
|
||||
out.print(tag);
|
||||
out.print(methodName + "_" + pc + "(");
|
||||
if (args.length > 0) {
|
||||
printObject(args[0]);
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
final Object arg = args[i];
|
||||
out.print(", ");
|
||||
|
||||
if (!(arg instanceof ScriptObject && ((ScriptObject) arg).isScope())) {
|
||||
printObject(arg);
|
||||
} else {
|
||||
out.print("SCOPE");
|
||||
}
|
||||
}
|
||||
}
|
||||
out.print(")");
|
||||
if (tag.equals("EXIT ")) {
|
||||
out.print(" --> ");
|
||||
printObject(result);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
}
|
212
src/main/java/org/bdware/sc/trace/ProgramPointCounter.java
Normal file
212
src/main/java/org/bdware/sc/trace/ProgramPointCounter.java
Normal file
@ -0,0 +1,212 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.sun.mail.iap.ByteArray;
|
||||
import org.bdware.analysis.CFGraph;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import wrp.jdk.nashorn.internal.runtime.TraceMethod;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ProgramPointCounter extends ContractProcess.Logger implements TraceMethod {
|
||||
public long gasLimit;
|
||||
public long extraGas;
|
||||
// PrintStream out;
|
||||
ByteArrayOutputStream bo;
|
||||
HashMap<Integer, Map<String, Integer>> ppc = new HashMap<>();
|
||||
String globalAction;
|
||||
HashMap<String, CFGraph> cfgMap;
|
||||
HashMap<String, Long> countMap;
|
||||
int functionIndex = 0;
|
||||
public long gasValue = 0;
|
||||
|
||||
public ProgramPointCounter(
|
||||
ByteArrayOutputStream bo,
|
||||
ContractProcess cp,
|
||||
long gasLimit,
|
||||
int functionIndex,
|
||||
long gasValue,
|
||||
long extraGas,
|
||||
String action,
|
||||
HashMap<String, Long> countMap) {
|
||||
super(new PrintStream(bo), cp);
|
||||
// out = System.out;
|
||||
this.bo = bo;
|
||||
globalAction = action;
|
||||
this.gasLimit = gasLimit - extraGas;
|
||||
this.functionIndex = functionIndex;
|
||||
this.countMap = countMap;
|
||||
this.gasValue = gasValue - extraGas;
|
||||
this.extraGas = extraGas;
|
||||
}
|
||||
|
||||
boolean simple = true;
|
||||
|
||||
@Override
|
||||
public String getOutputStr() {
|
||||
return bo.toString();
|
||||
}
|
||||
/*
|
||||
private void printObject(final Object arg) {
|
||||
if (simple) return;
|
||||
if (arg instanceof ScriptObject) {
|
||||
final ScriptObject object = (ScriptObject) arg;
|
||||
|
||||
boolean isFirst = true;
|
||||
final Set<Object> keySet = object.keySet();
|
||||
// System.out.println("[keySet:]");
|
||||
if (keySet.isEmpty()) {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
} else {
|
||||
out.print("{ ");
|
||||
|
||||
for (final Object key : keySet) {
|
||||
if (!isFirst) {
|
||||
out.print(", ");
|
||||
}
|
||||
|
||||
out.print(key);
|
||||
out.print(":");
|
||||
|
||||
final Object value = object.get(key);
|
||||
|
||||
if (value instanceof ScriptObject) {
|
||||
out.print("...");
|
||||
} else {
|
||||
printObject(value);
|
||||
}
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
out.print(" }");
|
||||
}
|
||||
} else {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
}
|
||||
}
|
||||
*/
|
||||
boolean initEnter = false;
|
||||
Stack<Integer> pcStack = new Stack<>();
|
||||
|
||||
@Override
|
||||
public void tracePrint(
|
||||
final String tag, int pc, String methodName, final Object[] args, final Object result) {
|
||||
// System.out.println("!@#$%^&*" + tag + pc + methodName + args + result);
|
||||
if (!initEnter) {
|
||||
// System.out.println("[functionIndex]:" + countMap.get(String.valueOf(functionIndex)));
|
||||
compareValue(String.valueOf(functionIndex));
|
||||
initEnter = true;
|
||||
}
|
||||
|
||||
if (tag.equals("EXIT ")) {
|
||||
// System.out.println(tag);
|
||||
if (pc == pcStack.peek()) {
|
||||
// System.out.println("出栈之前" + pcStack);
|
||||
pcStack.pop();
|
||||
if (countMap.containsKey(String.valueOf(pc))) {
|
||||
// System.out.println("出栈之后" + pcStack);
|
||||
compareValue(String.valueOf(pc));
|
||||
// System.out.println("弹出之后的消耗" + gasValue);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// System.out.println(tag);
|
||||
pcStack.push(pc);
|
||||
// System.out.println("入栈" + pcStack);
|
||||
}
|
||||
// out.print("[ProgramPointCounter] " + tag);
|
||||
// out.print(methodName + "_" + pc + "(");
|
||||
|
||||
// if (args.length > 0) {
|
||||
// printObject(args[0]);
|
||||
// for (int i = 1; i < args.length; i++) {
|
||||
// final Object arg = args[i];
|
||||
// out.print(", ");
|
||||
// if (!(arg instanceof ScriptObject && ((ScriptObject) arg).isScope())) {
|
||||
// printObject(arg);
|
||||
// } else {
|
||||
// out.print("SCOPE");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// out.print(")");
|
||||
// if (tag.equals("EXIT ")) {
|
||||
// out.print(" --> ");
|
||||
// printObject(result);
|
||||
// System.out.println("[result:]" + result);
|
||||
// }
|
||||
// out.println();
|
||||
// System.out.println("[Fee剩余]" + gasValue);
|
||||
}
|
||||
|
||||
public long cost = 0;
|
||||
|
||||
private void compareValue(String index) {
|
||||
if (gasValue > gasLimit) {
|
||||
System.out.println("out of gas");
|
||||
throw new IllegalStateException("gas out of limit");
|
||||
}
|
||||
cost = cost + countMap.get(index);
|
||||
// System.out.println("gasValue --:" + gasValue + " -" + countMap.get(index));
|
||||
|
||||
gasValue = gasValue - countMap.get(index);
|
||||
gasLimit = gasLimit - countMap.get(index);
|
||||
if (gasValue <= 0) {
|
||||
System.out.println("out of gas");
|
||||
throw new IllegalStateException("run out of InsnFee");
|
||||
} else if (gasLimit <= 0) {
|
||||
System.out.println("out of gas");
|
||||
throw new IllegalStateException("run over the limit");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String s) {
|
||||
super.println(s);
|
||||
// System.out.print("[s是:]"+s);
|
||||
// count++;
|
||||
// String oldTrace=traceCompare(s);
|
||||
// +=当前if与之前的if的指令权重或是指令数量。
|
||||
// if (count > 10) {
|
||||
// throw new IllegalStateException("run out of gas");
|
||||
// }
|
||||
try {
|
||||
JsonObject jo = new JsonParser().parse(s).getAsJsonObject();
|
||||
String traceMarkValue = jo.get("traceMark").getAsString();
|
||||
String val = jo.get("val").getAsString();
|
||||
// System.out.println(countMap);
|
||||
for (Map.Entry<String, Long> test : countMap.entrySet()) {
|
||||
if (test.getKey().contains(traceMarkValue)) {
|
||||
if (Integer.valueOf(val) <= 0 && test.getKey().contains("false")) {
|
||||
// System.out.println("false" + test.getKey());
|
||||
compareValue(test.getKey());
|
||||
} else if (Integer.valueOf(val) > 0 && test.getKey().contains("true")) {
|
||||
// System.out.println("true" + test.getKey());
|
||||
compareValue(test.getKey());
|
||||
// System.out.println("[gasLimit]"+gasValue+"[gasLimit]"+gasLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
// System.out.println("[Gas剩余]" + gasValue);
|
||||
// System.out.println("[执行消耗Gas]" + cost);
|
||||
// System.out.println("[额外Gas]" + extraGas);
|
||||
// System.out.println(
|
||||
// "[ProgramPointCounter] {\"traceMark\":"
|
||||
// + traceMarkValue
|
||||
// + "\"val\":"
|
||||
// + val
|
||||
// + "}");
|
||||
} catch (IllegalStateException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
11
src/main/java/org/bdware/sc/trace/Trace.java
Normal file
11
src/main/java/org/bdware/sc/trace/Trace.java
Normal file
@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Trace implements Serializable{
|
||||
|
||||
public String traceContent() {
|
||||
return "Trace Content";
|
||||
}
|
||||
|
||||
}
|
20
src/main/java/org/bdware/sc/trace/TraceDone.java
Normal file
20
src/main/java/org/bdware/sc/trace/TraceDone.java
Normal file
@ -0,0 +1,20 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TraceDone extends Trace implements Serializable {
|
||||
int id;
|
||||
|
||||
public TraceDone(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent() {
|
||||
return "[TraceDone] allocID:" + id + "\n";
|
||||
}
|
||||
}
|
51
src/main/java/org/bdware/sc/trace/TraceInitArray.java
Normal file
51
src/main/java/org/bdware/sc/trace/TraceInitArray.java
Normal file
@ -0,0 +1,51 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* 数组创建时有初始值,进行初始化
|
||||
*/
|
||||
public class TraceInitArray extends Trace implements Serializable{
|
||||
int arrayId; //被初始化的数组id
|
||||
List<Object> keys = new ArrayList<Object>(); //数组下标可能是整数,对象名等
|
||||
List<Object> values = new ArrayList<Object>(); //数组内内容
|
||||
|
||||
public TraceInitArray(int id) {
|
||||
this.arrayId = id;
|
||||
keys = new ArrayList<Object>();
|
||||
values = new ArrayList<Object>();
|
||||
}
|
||||
|
||||
public void put(Object key,Object value) {
|
||||
keys.add(key);
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return values.size();
|
||||
}
|
||||
|
||||
public int getArrayId() {
|
||||
return this.arrayId;
|
||||
}
|
||||
|
||||
public Object getKey(int i) {
|
||||
return keys.get(i);
|
||||
}
|
||||
|
||||
public Object getValue(int i) {
|
||||
return values.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent(){
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("[TraceInitArray]\n");
|
||||
str.append("ArrayID=" + arrayId + "\n");
|
||||
for(int i = 0;i < values.size();i++)
|
||||
str.append("key=" + keys.get(i) + ";value=" + values.get(i) + "\n");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
29
src/main/java/org/bdware/sc/trace/TraceInitObject.java
Normal file
29
src/main/java/org/bdware/sc/trace/TraceInitObject.java
Normal file
@ -0,0 +1,29 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TraceInitObject extends Trace implements Serializable{
|
||||
int id;
|
||||
int id2;
|
||||
|
||||
public TraceInitObject(int id,int id2) {
|
||||
this.id = id;
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("[TraceInitObject]\n");
|
||||
str.append("id=" + id + " ; id2=" + id2 + "\n");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user