Merge branch 'master' into secretstore_kovan
This commit is contained in:
commit
c0e7abcc81
84
.github/CODE_OF_CONDUCT.md
vendored
Normal file
84
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
## 1. Purpose
|
||||||
|
|
||||||
|
A primary goal of Parity is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).
|
||||||
|
|
||||||
|
This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.
|
||||||
|
|
||||||
|
We invite all those who participate in Parity to help us create safe and positive experiences for everyone.
|
||||||
|
|
||||||
|
## 2. Open Source Citizenship
|
||||||
|
|
||||||
|
A supplemental goal of this Code of Conduct is to increase open source citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community.
|
||||||
|
|
||||||
|
Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society.
|
||||||
|
|
||||||
|
If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know.
|
||||||
|
|
||||||
|
## 3. Expected Behavior
|
||||||
|
|
||||||
|
The following behaviors are expected and requested of all community members:
|
||||||
|
|
||||||
|
* Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community.
|
||||||
|
* Exercise consideration and respect in your speech and actions.
|
||||||
|
* Attempt collaboration before conflict.
|
||||||
|
* Refrain from demeaning, discriminatory, or harassing behavior and speech.
|
||||||
|
* Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential.
|
||||||
|
* Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations.
|
||||||
|
|
||||||
|
## 4. Unacceptable Behavior
|
||||||
|
|
||||||
|
The following behaviors are considered harassment and are unacceptable within our community:
|
||||||
|
|
||||||
|
* Violence, threats of violence or violent language directed against another person.
|
||||||
|
* Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language.
|
||||||
|
* Posting or displaying sexually explicit or violent material.
|
||||||
|
* Posting or threatening to post other people’s personally identifying information ("doxing").
|
||||||
|
* Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability.
|
||||||
|
* Inappropriate photography or recording.
|
||||||
|
* Inappropriate physical contact. You should have someone’s consent before touching them.
|
||||||
|
* Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances.
|
||||||
|
* Deliberate intimidation, stalking or following (online or in person).
|
||||||
|
* Advocating for, or encouraging, any of the above behavior.
|
||||||
|
* Sustained disruption of community events, including talks and presentations.
|
||||||
|
|
||||||
|
## 5. Consequences of Unacceptable Behavior
|
||||||
|
|
||||||
|
Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.
|
||||||
|
|
||||||
|
Anyone asked to stop unacceptable behavior is expected to comply immediately.
|
||||||
|
|
||||||
|
If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event).
|
||||||
|
|
||||||
|
## 6. Reporting Guidelines
|
||||||
|
|
||||||
|
If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. community@parity.io.
|
||||||
|
|
||||||
|
Link to reporting guidelines: [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||||
|
|
||||||
|
Link to security policy: [SECURITY.md](../SECURITY.md)
|
||||||
|
|
||||||
|
Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.
|
||||||
|
|
||||||
|
## 7. Addressing Grievances
|
||||||
|
|
||||||
|
If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify Parity Technologies with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies.
|
||||||
|
|
||||||
|
## 8. Scope
|
||||||
|
|
||||||
|
We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues–online and in-person–as well as in all one-on-one communications pertaining to community business.
|
||||||
|
|
||||||
|
This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members.
|
||||||
|
|
||||||
|
## 9. Contact info
|
||||||
|
|
||||||
|
You can contact Parity via Email: community@parity.io
|
||||||
|
|
||||||
|
## 10. License and attribution
|
||||||
|
|
||||||
|
This Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).
|
||||||
|
|
||||||
|
Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy).
|
||||||
|
|
||||||
|
Retrieved on November 22, 2016 from [http://citizencodeofconduct.org/](http://citizencodeofconduct.org/)
|
33
.github/CONTRIBUTING.md
vendored
Normal file
33
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Contributing Guidelines
|
||||||
|
|
||||||
|
## Do you have a question?
|
||||||
|
|
||||||
|
Check out our [Basic Usage](https://github.com/paritytech/parity/wiki/Basic-Usage), [Configuration](https://github.com/paritytech/parity/wiki/Configuring-Parity), and [FAQ](https://github.com/paritytech/parity/wiki/FAQ) articles on our [wiki](https://github.com/paritytech/parity/wiki)!
|
||||||
|
|
||||||
|
See also frequently asked questions [tagged with `parity`](https://ethereum.stackexchange.com/questions/tagged/parity?sort=votes&pageSize=50) on Stack Exchange.
|
||||||
|
|
||||||
|
## Report bugs!
|
||||||
|
|
||||||
|
Do **not** open an issue on Github if you think your discovered bug could be a **security-relevant vulnerability**. Please, read our [security policy](../SECURITY.md) instead.
|
||||||
|
|
||||||
|
Otherwise, just create a [new issue](https://github.com/paritytech/parity/issues/new) in our repository and state:
|
||||||
|
|
||||||
|
- What's your Parity version?
|
||||||
|
- What's your operating system and version?
|
||||||
|
- How did you install parity?
|
||||||
|
- Is your node fully synchronized?
|
||||||
|
- Did you try turning it off and on again?
|
||||||
|
|
||||||
|
Also, try to include **steps to reproduce** the issue and expand on the **actual versus expected behavior**.
|
||||||
|
|
||||||
|
## Contribute!
|
||||||
|
|
||||||
|
If you would like to contribute to Parity, please **fork it**, fix bugs or implement features, and [propose a pull request](https://github.com/paritytech/parity/compare).
|
||||||
|
|
||||||
|
Please, refer to the [Coding Guide](https://github.com/paritytech/parity/wiki/Coding-guide) in our wiki for more details about hacking on Parity.
|
||||||
|
|
||||||
|
## License.
|
||||||
|
|
||||||
|
By contributing to Parity, you agree that your contributions will be licensed under the [GPLv3 License](../LICENSE).
|
||||||
|
|
||||||
|
Each contributor has to sign our Contributor License Agreement. The purpose of the CLA is to ensure that the guardian of a project's outputs has the necessary ownership or grants of rights over all contributions to allow them to distribute under the chosen license. You can read and sign our full Contributor License Agreement at [cla.parity.io](https://cla.parity.io) before submitting a pull request.
|
45
CHANGELOG.md
45
CHANGELOG.md
@ -1,3 +1,48 @@
|
|||||||
|
## Parity [v1.8.4](https://github.com/paritytech/parity/releases/tag/v1.8.4) (2017-12-12)
|
||||||
|
|
||||||
|
Parity 1.8.4 applies fixes for Proof-of-Authority networks and schedules the Kovan-Byzantium hard-fork.
|
||||||
|
|
||||||
|
- The Kovan testnet will fork on block `5067000` at `Thu Dec 14 2017 05:40:03 UTC`.
|
||||||
|
- This enables Byzantium features on Kovan.
|
||||||
|
- This disables uncles on Kovan for stability reasons.
|
||||||
|
- Proof-of-Authority networks are advised to set `maximumUncleCount` to 0 in a future `maximumUncleCountTransition` for stability reasons.
|
||||||
|
- See the [Kovan chain spec](https://github.com/paritytech/parity/blob/master/ethcore/res/ethereum/kovan.json) for an example.
|
||||||
|
- New PoA networks created with Parity will have this feature enabled by default.
|
||||||
|
|
||||||
|
Furthermore, this release includes the ECIP-1039 Monetary policy rounding specification for Ethereum Classic, reduces the maximum Ethash-block timestamp drift to 15 seconds, and fixes various bugs for WASM and the RPC APIs.
|
||||||
|
|
||||||
|
The full list of included changes:
|
||||||
|
|
||||||
|
- Beta Backports and HF block update ([#7244](https://github.com/paritytech/parity/pull/7244))
|
||||||
|
- Reduce max block timestamp drift to 15 seconds ([#7240](https://github.com/paritytech/parity/pull/7240))
|
||||||
|
- Add test for block timestamp validation within allowed drift
|
||||||
|
- Update kovan HF block number.
|
||||||
|
- Beta Kovan HF ([#7234](https://github.com/paritytech/parity/pull/7234))
|
||||||
|
- Kovan HF.
|
||||||
|
- Bump version.
|
||||||
|
- Fix aura difficulty race ([#7198](https://github.com/paritytech/parity/pull/7198))
|
||||||
|
- Fix test key
|
||||||
|
- Extract out score calculation
|
||||||
|
- Fix build
|
||||||
|
- Update kovan HF block number.
|
||||||
|
- Add missing byzantium builtins.
|
||||||
|
- Bump installers versions.
|
||||||
|
- Increase allowed time drift to 10s. ([#7238](https://github.com/paritytech/parity/pull/7238))
|
||||||
|
- Beta Backports ([#7197](https://github.com/paritytech/parity/pull/7197))
|
||||||
|
- Maximum uncle count transition ([#7196](https://github.com/paritytech/parity/pull/7196))
|
||||||
|
- Enable delayed maximum_uncle_count activation.
|
||||||
|
- Fix tests.
|
||||||
|
- Defer kovan HF.
|
||||||
|
- Disable uncles by default ([#7006](https://github.com/paritytech/parity/pull/7006))
|
||||||
|
- Escape inifinite loop in estimte_gas ([#7075](https://github.com/paritytech/parity/pull/7075))
|
||||||
|
- ECIP-1039: Monetary policy rounding specification ([#7067](https://github.com/paritytech/parity/pull/7067))
|
||||||
|
- WASM Remove blockhash error ([#7121](https://github.com/paritytech/parity/pull/7121))
|
||||||
|
- Remove blockhash error
|
||||||
|
- Update tests.
|
||||||
|
- WASM storage_read and storage_write don't return anything ([#7110](https://github.com/paritytech/parity/pull/7110))
|
||||||
|
- WASM parse payload from panics ([#7097](https://github.com/paritytech/parity/pull/7097))
|
||||||
|
- Fix no-default-features. ([#7096](https://github.com/paritytech/parity/pull/7096))
|
||||||
|
|
||||||
## Parity [v1.8.3](https://github.com/paritytech/parity/releases/tag/v1.8.3) (2017-11-15)
|
## Parity [v1.8.3](https://github.com/paritytech/parity/releases/tag/v1.8.3) (2017-11-15)
|
||||||
|
|
||||||
Parity 1.8.3 contains several bug-fixes and removes the ability to deploy built-in multi-signature wallets.
|
Parity 1.8.3 contains several bug-fixes and removes the ability to deploy built-in multi-signature wallets.
|
||||||
|
138
Cargo.lock
generated
138
Cargo.lock
generated
@ -244,28 +244,6 @@ dependencies = [
|
|||||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clippy"
|
|
||||||
version = "0.0.103"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clippy_lints"
|
|
||||||
version = "0.0.103"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "coco"
|
name = "coco"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -480,7 +458,6 @@ dependencies = [
|
|||||||
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
||||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethash 1.9.0",
|
"ethash 1.9.0",
|
||||||
@ -554,6 +531,19 @@ dependencies = [
|
|||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethcore-bigint"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-bloom-journal"
|
name = "ethcore-bloom-journal"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -641,7 +631,6 @@ version = "1.9.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-bigint 0.2.1",
|
"ethcore-bigint 0.2.1",
|
||||||
"ethcore-bytes 0.1.0",
|
"ethcore-bytes 0.1.0",
|
||||||
@ -727,32 +716,14 @@ dependencies = [
|
|||||||
name = "ethcore-util"
|
name = "ethcore-util"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)",
|
|
||||||
"ethcore-bigint 0.2.1",
|
"ethcore-bigint 0.2.1",
|
||||||
"ethcore-bytes 0.1.0",
|
"ethcore-bytes 0.1.0",
|
||||||
"ethcore-logger 1.9.0",
|
|
||||||
"hashdb 0.1.1",
|
"hashdb 0.1.1",
|
||||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"journaldb 0.1.0",
|
|
||||||
"keccak-hash 0.1.0",
|
"keccak-hash 0.1.0",
|
||||||
"kvdb 0.1.0",
|
|
||||||
"kvdb-memorydb 0.1.0",
|
|
||||||
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memorydb 0.1.1",
|
"memorydb 0.1.1",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"patricia-trie 0.1.0",
|
"patricia-trie 0.1.0",
|
||||||
"rlp 0.2.1",
|
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"triehash 0.1.0",
|
"triehash 0.1.0",
|
||||||
"util-error 0.1.0",
|
|
||||||
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -771,7 +742,6 @@ dependencies = [
|
|||||||
name = "ethjson"
|
name = "ethjson"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ethcore-bigint 0.2.1",
|
"ethcore-bigint 0.2.1",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -853,7 +823,6 @@ dependencies = [
|
|||||||
name = "ethsync"
|
name = "ethsync"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.9.0",
|
"ethcore 1.9.0",
|
||||||
"ethcore-bigint 0.2.1",
|
"ethcore-bigint 0.2.1",
|
||||||
@ -1743,11 +1712,6 @@ dependencies = [
|
|||||||
"odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "1.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ntp"
|
name = "ntp"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -1916,7 +1880,6 @@ dependencies = [
|
|||||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
|
"ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)",
|
||||||
"daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1959,6 +1922,7 @@ dependencies = [
|
|||||||
"parity-rpc 1.9.0",
|
"parity-rpc 1.9.0",
|
||||||
"parity-rpc-client 1.4.0",
|
"parity-rpc-client 1.4.0",
|
||||||
"parity-updater 1.9.0",
|
"parity-updater 1.9.0",
|
||||||
|
"parity-version 0.1.0",
|
||||||
"parity-whisper 0.1.0",
|
"parity-whisper 0.1.0",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"path 0.1.0",
|
"path 0.1.0",
|
||||||
@ -1984,7 +1948,6 @@ name = "parity-dapps"
|
|||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore-bigint 0.2.1",
|
"ethcore-bigint 0.2.1",
|
||||||
"ethcore-bytes 0.1.0",
|
"ethcore-bytes 0.1.0",
|
||||||
@ -2005,6 +1968,7 @@ dependencies = [
|
|||||||
"parity-hash-fetch 1.9.0",
|
"parity-hash-fetch 1.9.0",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
"parity-ui 1.9.0",
|
"parity-ui 1.9.0",
|
||||||
|
"parity-version 0.1.0",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2020,7 +1984,6 @@ name = "parity-dapps-glue"
|
|||||||
version = "1.9.1"
|
version = "1.9.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2118,7 +2081,6 @@ version = "1.9.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ethash 1.9.0",
|
"ethash 1.9.0",
|
||||||
"ethcore 1.9.0",
|
"ethcore 1.9.0",
|
||||||
"ethcore-bigint 0.2.1",
|
"ethcore-bigint 0.2.1",
|
||||||
@ -2154,6 +2116,7 @@ dependencies = [
|
|||||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
"parity-updater 1.9.0",
|
"parity-updater 1.9.0",
|
||||||
|
"parity-version 0.1.0",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2234,7 +2197,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-old-precompiled"
|
name = "parity-ui-old-precompiled"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
source = "git+https://github.com/js-dist-paritytech/parity-master-1-9-v1.git#3c4b36c8f9b182242c1355289dc448eac95c19c5"
|
source = "git+https://github.com/js-dist-paritytech/parity-master-1-9-v1.git#d95164e94df10cb2bbcaa5dad36d6b61b760c3e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2242,7 +2205,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ui-precompiled"
|
name = "parity-ui-precompiled"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
source = "git+https://github.com/js-dist-paritytech/parity-master-1-9-shell.git#6dad0d219f9ad72f948f5f4138df3d6cf987b655"
|
source = "git+https://github.com/js-dist-paritytech/parity-master-1-9-shell.git#3bfd9abfca2ccadeb60aa6610ea0fbb9a8b74ac5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2261,12 +2224,24 @@ dependencies = [
|
|||||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-hash-fetch 1.9.0",
|
"parity-hash-fetch 1.9.0",
|
||||||
"parity-reactor 0.1.0",
|
"parity-reactor 0.1.0",
|
||||||
|
"parity-version 0.1.0",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"path 0.1.0",
|
"path 0.1.0",
|
||||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parity-version"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ethcore-bytes 0.1.0",
|
||||||
|
"rlp 0.2.1",
|
||||||
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-wasm"
|
name = "parity-wasm"
|
||||||
version = "0.15.3"
|
version = "0.15.3"
|
||||||
@ -2410,6 +2385,14 @@ dependencies = [
|
|||||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plain_hasher"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "podio"
|
name = "podio"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@ -2538,11 +2521,6 @@ name = "quick-error"
|
|||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quine-mc_cluskey"
|
|
||||||
version = "0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
@ -2603,11 +2581,6 @@ dependencies = [
|
|||||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -2836,14 +2809,6 @@ name = "semver"
|
|||||||
version = "0.1.20"
|
version = "0.1.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@ -3256,14 +3221,6 @@ dependencies = [
|
|||||||
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.1.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
@ -3277,6 +3234,16 @@ name = "traitobject"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "transaction-pool"
|
||||||
|
version = "1.9.0"
|
||||||
|
dependencies = [
|
||||||
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "transient-hashmap"
|
name = "transient-hashmap"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -3585,8 +3552,6 @@ dependencies = [
|
|||||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||||
"checksum cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34aa7da06f10541fbca6850719cdaa8fa03060a5d2fb33840f149cf8133a00c7"
|
"checksum cid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34aa7da06f10541fbca6850719cdaa8fa03060a5d2fb33840f149cf8133a00c7"
|
||||||
"checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2"
|
"checksum clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3451e409013178663435d6f15fdb212f14ee4424a3d74f979d081d0a66b6f1f2"
|
||||||
"checksum clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4fabf979ddf6419a313c1c0ada4a5b95cfd2049c56e8418d622d27b4b6ff32"
|
|
||||||
"checksum clippy_lints 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "ce96ec05bfe018a0d5d43da115e54850ea2217981ff0f2e462780ab9d594651a"
|
|
||||||
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
|
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
|
||||||
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
|
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
|
||||||
"checksum cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d53b80dde876f47f03cda35303e368a79b91c70b0d65ecba5fd5280944a08591"
|
"checksum cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d53b80dde876f47f03cda35303e368a79b91c70b0d65ecba5fd5280944a08591"
|
||||||
@ -3609,6 +3574,7 @@ dependencies = [
|
|||||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||||
"checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
|
"checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "<none>"
|
||||||
"checksum ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819a3adef0413a2519cbd9a19a35dd1c20c7a0110705beaba8aa4aa87eda95f"
|
"checksum ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819a3adef0413a2519cbd9a19a35dd1c20c7a0110705beaba8aa4aa87eda95f"
|
||||||
|
"checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5"
|
||||||
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
|
"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa"
|
||||||
"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423"
|
"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423"
|
||||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||||
@ -3679,7 +3645,6 @@ dependencies = [
|
|||||||
"checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5"
|
"checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5"
|
||||||
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
|
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
|
||||||
"checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
|
"checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
|
||||||
"checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
|
|
||||||
"checksum ntp 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "143149743832c6543b60a8ef2a26cd9122dfecec2b767158e852a7beecf6d7a0"
|
"checksum ntp 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "143149743832c6543b60a8ef2a26cd9122dfecec2b767158e852a7beecf6d7a0"
|
||||||
"checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525"
|
"checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525"
|
||||||
"checksum num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "8fd0f8dbb4c0960998958a796281d88c16fbe68d87b1baa6f31e2979e81fd0bd"
|
"checksum num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "8fd0f8dbb4c0960998958a796281d88c16fbe68d87b1baa6f31e2979e81fd0bd"
|
||||||
@ -3711,6 +3676,7 @@ dependencies = [
|
|||||||
"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
|
"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
|
||||||
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
|
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
|
||||||
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
||||||
|
"checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995"
|
||||||
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
|
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
|
||||||
"checksum pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2412f3332a07c7a2a50168988dcc184f32180a9758ad470390e5f55e089f6b6e"
|
"checksum pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2412f3332a07c7a2a50168988dcc184f32180a9758ad470390e5f55e089f6b6e"
|
||||||
"checksum primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0e31b86efadeaeb1235452171a66689682783149a6249ff334a2c5d8218d00a4"
|
"checksum primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0e31b86efadeaeb1235452171a66689682783149a6249ff334a2c5d8218d00a4"
|
||||||
@ -3724,7 +3690,6 @@ dependencies = [
|
|||||||
"checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
|
"checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
|
||||||
"checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd"
|
"checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd"
|
||||||
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
|
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
|
||||||
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
|
|
||||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
|
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
|
||||||
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
|
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
|
||||||
@ -3732,7 +3697,6 @@ dependencies = [
|
|||||||
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
|
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
|
||||||
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
|
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
|
||||||
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
|
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
|
||||||
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
|
|
||||||
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
|
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
|
||||||
"checksum reqwest 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5866613d84e2a39c0479a960bf2d0eff1fbfc934f02cd42b5c08c1e1efc5b1fd"
|
"checksum reqwest 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5866613d84e2a39c0479a960bf2d0eff1fbfc934f02cd42b5c08c1e1efc5b1fd"
|
||||||
"checksum ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "24293de46bac74c9b9c05b40ff8496bbc8b9ae242a9b89f754e1154a43bc7c4c"
|
"checksum ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "24293de46bac74c9b9c05b40ff8496bbc8b9ae242a9b89f754e1154a43bc7c4c"
|
||||||
@ -3755,7 +3719,6 @@ dependencies = [
|
|||||||
"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332"
|
"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332"
|
||||||
"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead"
|
"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead"
|
||||||
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||||
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
|
|
||||||
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
||||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
"checksum serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7046c9d4c6c522d10b2d098f9bebe2bef227e0e74044d8c1bfcf6b476af799"
|
"checksum serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7046c9d4c6c522d10b2d098f9bebe2bef227e0e74044d8c1bfcf6b476af799"
|
||||||
@ -3803,7 +3766,6 @@ dependencies = [
|
|||||||
"checksum tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc"
|
"checksum tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc"
|
||||||
"checksum tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d88e411cac1c87e405e4090be004493c5d8072a370661033b1a64ea205ec2e13"
|
"checksum tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d88e411cac1c87e405e4090be004493c5d8072a370661033b1a64ea205ec2e13"
|
||||||
"checksum tokio-uds 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6116c71be48f8f1656551fd16458247fdd6c03201d7893ad81189055fcde03e8"
|
"checksum tokio-uds 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6116c71be48f8f1656551fd16458247fdd6c03201d7893ad81189055fcde03e8"
|
||||||
"checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
|
|
||||||
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
|
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
|
||||||
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
||||||
"checksum transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "715254c8f0811be1a79ad3ea5e6fa3c8eddec2b03d7f5ba78cf093e56d79c24f"
|
"checksum transient-hashmap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "715254c8f0811be1a79ad3ea5e6fa3c8eddec2b03d7f5ba78cf093e56d79c24f"
|
||||||
|
15
Cargo.toml
15
Cargo.toml
@ -55,6 +55,7 @@ parity-reactor = { path = "util/reactor" }
|
|||||||
parity-rpc = { path = "rpc" }
|
parity-rpc = { path = "rpc" }
|
||||||
parity-rpc-client = { path = "rpc_client" }
|
parity-rpc-client = { path = "rpc_client" }
|
||||||
parity-updater = { path = "updater" }
|
parity-updater = { path = "updater" }
|
||||||
|
parity-version = { path = "util/version" }
|
||||||
parity-whisper = { path = "whisper" }
|
parity-whisper = { path = "whisper" }
|
||||||
path = { path = "util/path" }
|
path = { path = "util/path" }
|
||||||
panic_hook = { path = "panic_hook" }
|
panic_hook = { path = "panic_hook" }
|
||||||
@ -65,7 +66,6 @@ kvdb-rocksdb = { path = "util/kvdb-rocksdb" }
|
|||||||
journaldb = { path = "util/journaldb" }
|
journaldb = { path = "util/journaldb" }
|
||||||
|
|
||||||
parity-dapps = { path = "dapps", optional = true }
|
parity-dapps = { path = "dapps", optional = true }
|
||||||
clippy = { version = "0.0.103", optional = true}
|
|
||||||
ethcore-secretstore = { path = "secret_store", optional = true }
|
ethcore-secretstore = { path = "secret_store", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
@ -94,13 +94,11 @@ ui-precompiled = [
|
|||||||
ui-enabled = ["dapps"]
|
ui-enabled = ["dapps"]
|
||||||
dapps = ["parity-dapps"]
|
dapps = ["parity-dapps"]
|
||||||
jit = ["ethcore/jit"]
|
jit = ["ethcore/jit"]
|
||||||
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "parity-rpc/dev", "parity-dapps/dev"]
|
|
||||||
json-tests = ["ethcore/json-tests"]
|
json-tests = ["ethcore/json-tests"]
|
||||||
test-heavy = ["ethcore/test-heavy"]
|
test-heavy = ["ethcore/test-heavy"]
|
||||||
evm-debug = ["ethcore/evm-debug"]
|
evm-debug = ["ethcore/evm-debug"]
|
||||||
evm-debug-tests = ["ethcore/evm-debug-tests"]
|
evm-debug-tests = ["ethcore/evm-debug-tests"]
|
||||||
slow-blocks = ["ethcore/slow-blocks"]
|
slow-blocks = ["ethcore/slow-blocks"]
|
||||||
final = ["ethcore-util/final"]
|
|
||||||
secretstore = ["ethcore-secretstore"]
|
secretstore = ["ethcore-secretstore"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
@ -116,4 +114,13 @@ lto = false
|
|||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["ethstore/cli", "ethkey/cli", "evmbin", "whisper", "chainspec", "dapps/js-glue", "ethcore/wasm/run"]
|
members = [
|
||||||
|
"chainspec",
|
||||||
|
"dapps/js-glue",
|
||||||
|
"ethcore/wasm/run",
|
||||||
|
"ethkey/cli",
|
||||||
|
"ethstore/cli",
|
||||||
|
"evmbin",
|
||||||
|
"transaction-pool",
|
||||||
|
"whisper",
|
||||||
|
]
|
||||||
|
13
README.md
13
README.md
@ -94,12 +94,25 @@ $ cargo build --release
|
|||||||
```
|
```
|
||||||
|
|
||||||
This will produce an executable in the `./target/release` subdirectory.
|
This will produce an executable in the `./target/release` subdirectory.
|
||||||
|
|
||||||
Note: if cargo fails to parse manifest try:
|
Note: if cargo fails to parse manifest try:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ~/.cargo/bin/cargo build --release
|
$ ~/.cargo/bin/cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note: When compiling a crate and you receive the following error:
|
||||||
|
|
||||||
|
```
|
||||||
|
error: the crate is compiled with the panic strategy `abort` which is incompatible with this crate's strategy of `unwind`
|
||||||
|
```
|
||||||
|
|
||||||
|
Cleaning the repository will most likely solve the issue, try:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cargo clean
|
||||||
|
```
|
||||||
|
|
||||||
This will always compile the latest nightly builds. If you want to build stable or beta, do a `git checkout stable` or `git checkout beta` first.
|
This will always compile the latest nightly builds. If you want to build stable or beta, do a `git checkout stable` or `git checkout beta` first.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
@ -37,15 +37,12 @@ parity-hash-fetch = { path = "../hash-fetch" }
|
|||||||
parity-reactor = { path = "../util/reactor" }
|
parity-reactor = { path = "../util/reactor" }
|
||||||
parity-ui = { path = "./ui" }
|
parity-ui = { path = "./ui" }
|
||||||
keccak-hash = { path = "../util/hash" }
|
keccak-hash = { path = "../util/hash" }
|
||||||
|
parity-version = { path = "../util/version" }
|
||||||
clippy = { version = "0.0.103", optional = true}
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.4"
|
env_logger = "0.4"
|
||||||
ethcore-devtools = { path = "../devtools" }
|
ethcore-devtools = { path = "../devtools" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
dev = ["clippy", "ethcore-util/dev"]
|
|
||||||
|
|
||||||
ui = ["parity-ui/no-precompiled-js"]
|
ui = ["parity-ui/no-precompiled-js"]
|
||||||
ui-precompiled = ["parity-ui/use-precompiled-js"]
|
ui-precompiled = ["parity-ui/use-precompiled-js"]
|
||||||
|
@ -18,13 +18,10 @@ quasi = { version = "0.32", default-features = false }
|
|||||||
quasi_macros = { version = "0.32", optional = true }
|
quasi_macros = { version = "0.32", optional = true }
|
||||||
syntex = { version = "0.58", optional = true }
|
syntex = { version = "0.58", optional = true }
|
||||||
syntex_syntax = { version = "0.58", optional = true }
|
syntex_syntax = { version = "0.58", optional = true }
|
||||||
clippy = { version = "0.0.103", optional = true }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
dev = ["clippy"]
|
|
||||||
default = ["with-syntex"]
|
default = ["with-syntex"]
|
||||||
nightly = ["quasi_macros"]
|
nightly = ["quasi_macros"]
|
||||||
nightly-testing = ["clippy"]
|
|
||||||
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
|
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
|
||||||
use-precompiled-js = []
|
use-precompiled-js = []
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ const UPDATE_TIMEOUT_ERR_SECS: u64 = 60;
|
|||||||
const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10;
|
const UPDATE_TIMEOUT_INCOMPLETE_SECS: u64 = 10;
|
||||||
|
|
||||||
/// Maximal valid time drift.
|
/// Maximal valid time drift.
|
||||||
pub const MAX_DRIFT: i64 = 500;
|
pub const MAX_DRIFT: i64 = 10_000;
|
||||||
|
|
||||||
type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
||||||
|
|
||||||
|
@ -200,8 +200,10 @@ impl<R: URLHint + 'static, F: Fetch> Endpoint for ContentFetcher<F, R> {
|
|||||||
Some(URLHintResult::Dapp(_)) if self.only_content => {
|
Some(URLHintResult::Dapp(_)) if self.only_content => {
|
||||||
(None, Self::dapps_disabled(self.embeddable_on.clone()))
|
(None, Self::dapps_disabled(self.embeddable_on.clone()))
|
||||||
},
|
},
|
||||||
Some(URLHintResult::Dapp(dapp)) => {
|
Some(content) => {
|
||||||
let handler = ContentFetcherHandler::new(
|
let handler = match content {
|
||||||
|
URLHintResult::Dapp(dapp) => {
|
||||||
|
ContentFetcherHandler::new(
|
||||||
req.method(),
|
req.method(),
|
||||||
&dapp.url(),
|
&dapp.url(),
|
||||||
path,
|
path,
|
||||||
@ -214,12 +216,26 @@ impl<R: URLHint + 'static, F: Fetch> Endpoint for ContentFetcher<F, R> {
|
|||||||
),
|
),
|
||||||
self.embeddable_on.clone(),
|
self.embeddable_on.clone(),
|
||||||
self.fetch.clone(),
|
self.fetch.clone(),
|
||||||
);
|
)
|
||||||
|
|
||||||
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
|
||||||
},
|
},
|
||||||
Some(URLHintResult::Content(content)) => {
|
URLHintResult::GithubDapp(content) => {
|
||||||
let handler = ContentFetcherHandler::new(
|
ContentFetcherHandler::new(
|
||||||
|
req.method(),
|
||||||
|
&content.url,
|
||||||
|
path,
|
||||||
|
installers::Dapp::new(
|
||||||
|
content_id.clone(),
|
||||||
|
self.cache_path.clone(),
|
||||||
|
Box::new(on_done),
|
||||||
|
self.embeddable_on.clone(),
|
||||||
|
self.pool.clone(),
|
||||||
|
),
|
||||||
|
self.embeddable_on.clone(),
|
||||||
|
self.fetch.clone(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
URLHintResult::Content(content) => {
|
||||||
|
ContentFetcherHandler::new(
|
||||||
req.method(),
|
req.method(),
|
||||||
&content.url,
|
&content.url,
|
||||||
path,
|
path,
|
||||||
@ -232,7 +248,9 @@ impl<R: URLHint + 'static, F: Fetch> Endpoint for ContentFetcher<F, R> {
|
|||||||
),
|
),
|
||||||
self.embeddable_on.clone(),
|
self.embeddable_on.clone(),
|
||||||
self.fetch.clone(),
|
self.fetch.clone(),
|
||||||
);
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
use hyper::{self, mime, header};
|
use hyper::{self, mime, header};
|
||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
|
|
||||||
use util::version;
|
use parity_version::version;
|
||||||
|
|
||||||
use handlers::add_security_headers;
|
use handlers::add_security_headers;
|
||||||
use Embeddable;
|
use Embeddable;
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
//! Ethcore Webapplications for Parity
|
//! Ethcore Webapplications for Parity
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![cfg_attr(feature="nightly", feature(plugin))]
|
|
||||||
#![cfg_attr(feature="nightly", plugin(clippy))]
|
|
||||||
|
|
||||||
extern crate base32;
|
extern crate base32;
|
||||||
extern crate futures_cpupool;
|
extern crate futures_cpupool;
|
||||||
@ -43,6 +41,7 @@ extern crate parity_dapps_glue as parity_dapps;
|
|||||||
extern crate parity_hash_fetch as hash_fetch;
|
extern crate parity_hash_fetch as hash_fetch;
|
||||||
extern crate parity_ui;
|
extern crate parity_ui;
|
||||||
extern crate keccak_hash as hash;
|
extern crate keccak_hash as hash;
|
||||||
|
extern crate parity_version;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
use hyper::{self, header, StatusCode};
|
use hyper::{self, header, StatusCode};
|
||||||
use hyper::mime::Mime;
|
use hyper::mime::{self, Mime};
|
||||||
|
|
||||||
|
use apps;
|
||||||
use handlers::{Reader, ContentHandler, add_security_headers};
|
use handlers::{Reader, ContentHandler, add_security_headers};
|
||||||
use {Embeddable};
|
use {Embeddable};
|
||||||
|
|
||||||
@ -95,7 +96,18 @@ impl<T: DappFile> PageHandler<T> {
|
|||||||
add_security_headers(&mut headers, self.safe_to_embed_on);
|
add_security_headers(&mut headers, self.safe_to_embed_on);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (reader, body) = Reader::pair(file.into_reader(), Vec::new());
|
let initial_content = if file.content_type().to_owned() == mime::TEXT_HTML {
|
||||||
|
let content = &format!(
|
||||||
|
r#"<script src="/{}/inject.js"></script>"#,
|
||||||
|
apps::UTILS_PATH,
|
||||||
|
);
|
||||||
|
|
||||||
|
content.as_bytes().to_vec()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
let (reader, body) = Reader::pair(file.into_reader(), initial_content);
|
||||||
res.set_body(body);
|
res.set_body(body);
|
||||||
(Some(reader), res)
|
(Some(reader), res)
|
||||||
}
|
}
|
||||||
|
@ -166,14 +166,15 @@ fn should_return_fetched_dapp_content() {
|
|||||||
|
|
||||||
response1.assert_status("HTTP/1.1 200 OK");
|
response1.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_security_headers_for_embed(&response1.headers);
|
assert_security_headers_for_embed(&response1.headers);
|
||||||
assert_eq!(
|
assert!(
|
||||||
response1.body,
|
response1.body.contains(r#"18
|
||||||
r#"18
|
|
||||||
<h1>Hello Gavcoin!</h1>
|
<h1>Hello Gavcoin!</h1>
|
||||||
|
|
||||||
0
|
0
|
||||||
|
|
||||||
"#
|
"#),
|
||||||
|
"Expected Gavcoin body: {}",
|
||||||
|
response1.body
|
||||||
);
|
);
|
||||||
|
|
||||||
response2.assert_status("HTTP/1.1 200 OK");
|
response2.assert_status("HTTP/1.1 200 OK");
|
||||||
|
@ -60,3 +60,32 @@ fn should_serve_home() {
|
|||||||
response.assert_header("Content-Type", "text/html");
|
response.assert_header("Content-Type", "text/html");
|
||||||
assert_security_headers(&response.headers);
|
assert_security_headers(&response.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_inject_js() {
|
||||||
|
// given
|
||||||
|
let server = serve_ui();
|
||||||
|
|
||||||
|
// when
|
||||||
|
let response = request(server,
|
||||||
|
"\
|
||||||
|
GET / HTTP/1.1\r\n\
|
||||||
|
Host: 127.0.0.1:8080\r\n\
|
||||||
|
Connection: close\r\n\
|
||||||
|
\r\n\
|
||||||
|
{}
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
response.assert_status("HTTP/1.1 200 OK");
|
||||||
|
response.assert_header("Content-Type", "text/html");
|
||||||
|
assert_eq!(
|
||||||
|
response.body.contains(r#"/inject.js"></script>"#),
|
||||||
|
true,
|
||||||
|
"Expected inject script tag in: {}",
|
||||||
|
response.body
|
||||||
|
);
|
||||||
|
assert_security_headers(&response.headers);
|
||||||
|
}
|
||||||
|
@ -1,3 +1,35 @@
|
|||||||
|
### Parity [v1.7.10](https://github.com/paritytech/parity/releases/tag/v1.7.10) (2017-12-11)
|
||||||
|
|
||||||
|
Parity 1.7.10 applies fixes for Proof-of-Authority networks and schedules the Kovan-Byzantium hard-fork.
|
||||||
|
|
||||||
|
- The Kovan testnet will fork on block `5067000` at `Thu Dec 14 2017 05:40:03 UTC`.
|
||||||
|
- This enables Byzantium features on Kovan.
|
||||||
|
- This disables uncles on Kovan for stability reasons.
|
||||||
|
- Proof-of-Authority networks are advised to set `maximumUncleCount` to 0 in a future `maximumUncleCountTransition` for stability reasons. See the [Kovan chain spec](https://github.com/paritytech/parity/blob/master/ethcore/res/ethereum/kovan.json) for an example. New PoA networks created with Parity will have this feature enabled by default.
|
||||||
|
|
||||||
|
The full list of included changes:
|
||||||
|
|
||||||
|
- Backports and HF block update ([#7243](https://github.com/paritytech/parity/pull/7243))
|
||||||
|
- Reduce max block timestamp drift to 15 seconds ([#7240](https://github.com/paritytech/parity/pull/7240))
|
||||||
|
- Add test for block timestamp validation within allowed drift
|
||||||
|
- Update kovan HF block number. ([#7259](https://github.com/paritytech/parity/pull/7259))
|
||||||
|
- [stable] Backports and Kovan HF ([#7235](https://github.com/paritytech/parity/pull/7235))
|
||||||
|
- Escape inifinite loop in estimte_gas ([#7075](https://github.com/paritytech/parity/pull/7075))
|
||||||
|
- Disable uncles by default ([#7006](https://github.com/paritytech/parity/pull/7006))
|
||||||
|
- Maximum uncle count transition ([#7196](https://github.com/paritytech/parity/pull/7196))
|
||||||
|
- Enable delayed maximum_uncle_count activation.
|
||||||
|
- Fix tests.
|
||||||
|
- Defer kovan HF.
|
||||||
|
- Bump version.
|
||||||
|
- Kovan HF.
|
||||||
|
- Update Kovan HF block.
|
||||||
|
- Fix compilation issues.
|
||||||
|
- Fix aura test.
|
||||||
|
- Add missing byzantium builtins.
|
||||||
|
- Fix tests.
|
||||||
|
- Bump version for installers.
|
||||||
|
- Increase allowed time drift to 10s. ([#7238](https://github.com/paritytech/parity/pull/7238))
|
||||||
|
|
||||||
### Parity [v1.7.9](https://github.com/paritytech/parity/releases/tag/v1.7.9) (2017-11-14)
|
### Parity [v1.7.9](https://github.com/paritytech/parity/releases/tag/v1.7.9) (2017-11-14)
|
||||||
|
|
||||||
Parity 1.7.9 removes the ability to deploy built-in multi-signature wallets.
|
Parity 1.7.9 removes the ability to deploy built-in multi-signature wallets.
|
||||||
|
@ -11,7 +11,6 @@ ansi_term = "0.9"
|
|||||||
bloomchain = "0.1"
|
bloomchain = "0.1"
|
||||||
bn = { git = "https://github.com/paritytech/bn" }
|
bn = { git = "https://github.com/paritytech/bn" }
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
clippy = { version = "0.0.103", optional = true}
|
|
||||||
common-types = { path = "types" }
|
common-types = { path = "types" }
|
||||||
crossbeam = "0.2.9"
|
crossbeam = "0.2.9"
|
||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
@ -83,6 +82,5 @@ evm-debug-tests = ["evm-debug"]
|
|||||||
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
|
slow-blocks = [] # Use SLOW_TX_DURATION="50" (compile time!) to track transactions over 50ms
|
||||||
json-tests = []
|
json-tests = []
|
||||||
test-heavy = []
|
test-heavy = []
|
||||||
dev = ["clippy"]
|
|
||||||
default = []
|
default = []
|
||||||
benches = []
|
benches = []
|
||||||
|
@ -32,7 +32,6 @@ macro_rules! overflowing {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
|
||||||
enum Request<Cost: ::evm::CostType> {
|
enum Request<Cost: ::evm::CostType> {
|
||||||
Gas(Cost),
|
Gas(Cost),
|
||||||
GasMem(Cost, Cost),
|
GasMem(Cost, Cost),
|
||||||
@ -101,7 +100,6 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
|
||||||
/// Determine how much gas is used by the given instruction, given the machine's state.
|
/// Determine how much gas is used by the given instruction, given the machine's state.
|
||||||
///
|
///
|
||||||
/// We guarantee that the final element of the returned tuple (`provided`) will be `Some`
|
/// We guarantee that the final element of the returned tuple (`provided`) will be `Some`
|
||||||
|
@ -66,7 +66,6 @@ struct CodeReader<'a> {
|
|||||||
code: &'a [u8]
|
code: &'a [u8]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(len_without_is_empty))]
|
|
||||||
impl<'a> CodeReader<'a> {
|
impl<'a> CodeReader<'a> {
|
||||||
|
|
||||||
/// Create new code reader - starting at position 0.
|
/// Create new code reader - starting at position 0.
|
||||||
@ -287,7 +286,6 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
fn exec_instruction(
|
fn exec_instruction(
|
||||||
&mut self,
|
&mut self,
|
||||||
gas: Cost,
|
gas: Cost,
|
||||||
|
72
ethcore/res/ethereum/ellaism.json
Normal file
72
ethcore/res/ethereum/ellaism.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"name": "Ellaism",
|
||||||
|
"dataDir": "ellaism",
|
||||||
|
"engine": {
|
||||||
|
"Ethash": {
|
||||||
|
"params": {
|
||||||
|
"minimumDifficulty": "0x020000",
|
||||||
|
"difficultyBoundDivisor": "0x0800",
|
||||||
|
"durationLimit": "0x0d",
|
||||||
|
"blockReward": "0x4563918244F40000",
|
||||||
|
"homesteadTransition": "0x0",
|
||||||
|
"bombDefuseTransition": "0x0",
|
||||||
|
"eip150Transition": "0x0",
|
||||||
|
"eip160Transition": "0x0",
|
||||||
|
"ecip1017EraRounds": 10000000,
|
||||||
|
|
||||||
|
"eip161abcTransition": "0x7fffffffffffffff",
|
||||||
|
"eip161dTransition": "0x7fffffffffffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x0400",
|
||||||
|
"registrar": "0x3bb2bb5c6c9c9b7f4EF430b47Dc7e026310042ea",
|
||||||
|
"accountStartNonce": "0x00",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"networkID": "0x40",
|
||||||
|
"chainID": "0x40",
|
||||||
|
"eip155Transition": "0x0",
|
||||||
|
"eip98Transition": "0x7fffffffffffff",
|
||||||
|
"eip86Transition": "0x7fffffffffffff"
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"seal": {
|
||||||
|
"ethereum": {
|
||||||
|
"nonce": "0x0000000000000040",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"difficulty": "0x40000000",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"gasLimit": "0x1388"
|
||||||
|
},
|
||||||
|
"nodes": [
|
||||||
|
"enode://98b48cc7149326d00a57994ad55014a095a3e5cd4f0144cd7b034fb667d8e8017082bd90047d72c4403798b8ece11a33bd2e344d6500faba30889ebcfa5316fa@172.104.163.204:30303",
|
||||||
|
"enode://834246cc2a7584df29ccdcf3b5366f118a0e291264980376769e809665a02c4caf0d68c43eecf8390dbeaf861823b05583807af0a62542a1f3f717046b958a76@45.77.106.33:30303",
|
||||||
|
"enode://d1373d7187a20d695220fafb5746a289786bad92469d6bbe800f07572f8f444479f507cfcb8fcd8f5bee5dd44efb6185df4a1e4f1a7170408ada9876ef5b3fe4@178.79.189.58:30303",
|
||||||
|
"enode://d8059dcb137cb52b8960ca82613eeba1d121105572decd8f1d3ea22b09070645eeab548d2a3cd2914f206e1331c7870bd2bd5a231ebac6b3d4886ec3b8e627e5@173.212.216.105:30303",
|
||||||
|
"enode://5a89c8664d29a321fd4cb1b55b0f0be832ce376b5e7feb14a2073fdbd9bd7b7394169ed289dd991112b42ecfb74ea36e436bc72a1c99dcdb50d96eaf3b0ed254@213.136.91.42:30303",
|
||||||
|
"enode://9215ad77bd081e35013cb42a8ceadff9d8e94a78fcc680dff1752a54e7484badff0904e331c4b40a68be593782e55acfd800f076d22f9d2832e8483733ade149@213.14.82.125:30303",
|
||||||
|
"enode://07913818dafbadf44d4fc796fa414ec1d720ecfb087eff37efbe7134556658e92351559de788fa319c291e40b915cc26d902069d03bd935553d4efa688bdbbf8@45.32.19.37:30303",
|
||||||
|
"enode://645a59b6e6e20ed8864767a1d0c731f89ae276ed4e04c4f10becce655532d95cbe1bc9e2da3f13a6564f9ca8fe46fab2781a380b3a89148bccac883d6068f684@45.77.159.123:30303",
|
||||||
|
"enode://7c2f43b2e7fded9469917311574d267427e62cd12e1864effd15f31c1246e4e955463d843acaa37309693a515df7986cb6d160b7e85a4ca2779a798a72d90850@108.61.194.191:30303",
|
||||||
|
"enode://5dd35866da95aea15211fb1f98684f6e8c4e355e6aa3cc17585680ed53fa164477b8c52cb6ca4b24ec4d80f3d48ff9212b53feb131d825c7945a3abaaf02d24d@178.79.189.58:60606",
|
||||||
|
"enode://6c585c18024eb902ca093278af73b04863ac904caabc39ac2920c23532307c572ad92afd828a990c980d272b1f26307f2409cc97aec3ff9fe866732cae49a8c2@144.217.163.224:31337",
|
||||||
|
"enode://edd90c4cc64528802ad52fd127d80b641ff80fd43fa5292fb111c8bd2914482dffee288fd1b0d26440c6b2c669b10a53cbcd37c895ba0d6194110e100a965b2d@188.166.179.159:30303",
|
||||||
|
"enode://d19783546438e8bfc11a35457ff1f47871a2ce4801b9b2dbe7606321a9ce29007305497eb8c98d7ae9dc5a913ee5533c3691b1080f7066697c4276e6140d2eac@45.77.47.184:30303",
|
||||||
|
"enode://13ed57615447bc9bf1da4e28249369babc00d2530d6c103c12350453e469a5e90cbcdb787c436977467f5864be6e64f2520180fc60b841c8c3daf84df9450190@104.207.152.17:30303",
|
||||||
|
"enode://59c228a6a0939a0b53edf6924bc7bd1384652dc1da0777495acd0707975f485f54a77c7b2dcbeece9340a43ccd9c7ea70f0cdfe48936537d238b50e5cb5dc0b2@45.77.233.0:30303",
|
||||||
|
"enode://9d960373335c1cc38ca696dea8f2893e2a071c8f21524f21e8aae22be032acc3b67797b1d21e866f9d832943ae7d9555b8466c6ab34f473d21e547114952df37@213.32.53.183:30303"
|
||||||
|
],
|
||||||
|
"accounts": {
|
||||||
|
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
|
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
|
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
||||||
|
}
|
||||||
|
}
|
@ -173,6 +173,11 @@
|
|||||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||||
},
|
},
|
||||||
"nodes": [
|
"nodes": [
|
||||||
|
"enode://5a62f19d35c0da8b576c9414568c728d4744e6e9d436c0f9db27456400011414f515871f13a6b8e0468534b5116cfe765d7630f680f1707a38467940a9f62511@45.55.33.62:30303",
|
||||||
|
"enode://605e04a43b1156966b3a3b66b980c87b7f18522f7f712035f84576016be909a2798a438b2b17b1a8c58db314d88539a77419ca4be36148c086900fba487c9d39@188.166.255.12:30303",
|
||||||
|
"enode://dc72806c3aa8fda207c8c018aba8d6cf143728b3628b6ded8d5e8cdeb8aa05cbd53f710ecd014c9a8f0d1e98f2874bff8afb15a229202f510a9c0258d1f6d109@159.203.210.80:30303",
|
||||||
|
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
|
||||||
|
"enode://2c9059f05c352b29d559192fe6bca272d965c9f2290632a2cfda7f83da7d2634f3ec45ae3a72c54dd4204926fb8082dcf9686e0d7504257541c86fc8569bcf4b@163.172.171.38:30303",
|
||||||
"enode://efe4f2493f4aff2d641b1db8366b96ddacfe13e7a6e9c8f8f8cf49f9cdba0fdf3258d8c8f8d0c5db529f8123c8f1d95f36d54d590ca1bb366a5818b9a4ba521c@163.172.187.252:30303",
|
"enode://efe4f2493f4aff2d641b1db8366b96ddacfe13e7a6e9c8f8f8cf49f9cdba0fdf3258d8c8f8d0c5db529f8123c8f1d95f36d54d590ca1bb366a5818b9a4ba521c@163.172.187.252:30303",
|
||||||
"enode://cd6611461840543d5b9c56fbf088736154c699c43973b3a1a32390cf27106f87e58a818a606ccb05f3866de95a4fe860786fea71bf891ea95f234480d3022aa3@163.172.157.114:30303",
|
"enode://cd6611461840543d5b9c56fbf088736154c699c43973b3a1a32390cf27106f87e58a818a606ccb05f3866de95a4fe860786fea71bf891ea95f234480d3022aa3@163.172.157.114:30303",
|
||||||
"enode://bcc7240543fe2cf86f5e9093d05753dd83343f8fda7bf0e833f65985c73afccf8f981301e13ef49c4804491eab043647374df1c4adf85766af88a624ecc3330e@136.243.154.244:30303",
|
"enode://bcc7240543fe2cf86f5e9093d05753dd83343f8fda7bf0e833f65985c73afccf8f981301e13ef49c4804491eab043647374df1c4adf85766af88a624ecc3330e@136.243.154.244:30303",
|
||||||
@ -184,13 +189,7 @@
|
|||||||
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
|
||||||
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
|
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
|
||||||
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
|
||||||
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303",
|
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303"
|
||||||
|
|
||||||
"enode://89d5dc2a81e574c19d0465f497c1af96732d1b61a41de89c2a37f35707689ac416529fae1038809852b235c2d30fd325abdc57c122feeefbeaaf802cc7e9580d@45.55.33.62:30303",
|
|
||||||
"enode://605e04a43b1156966b3a3b66b980c87b7f18522f7f712035f84576016be909a2798a438b2b17b1a8c58db314d88539a77419ca4be36148c086900fba487c9d39@188.166.255.12:30303",
|
|
||||||
"enode://016b20125f447a3b203a3cae953b2ede8ffe51290c071e7599294be84317635730c397b8ff74404d6be412d539ee5bb5c3c700618723d3b53958c92bd33eaa82@159.203.210.80:30303",
|
|
||||||
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
|
|
||||||
"enode://8d91c8137890d29110b9463882f17ae4e279cd2c90cf56573187ed1c8546fca5f590a9f05e9f108eb1bd91767ed01ede4daad9e001b61727885eaa246ddb39c2@163.172.171.38:30303"
|
|
||||||
],
|
],
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
|
@ -12,19 +12,17 @@
|
|||||||
"0x00427feae2419c15b89d1c21af10d1b6650a4d3d",
|
"0x00427feae2419c15b89d1c21af10d1b6650a4d3d",
|
||||||
"0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c",
|
"0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c",
|
||||||
"0x0020ee4Be0e2027d76603cB751eE069519bA81A1",
|
"0x0020ee4Be0e2027d76603cB751eE069519bA81A1",
|
||||||
|
|
||||||
"0x0010f94b296a852aaac52ea6c5ac72e03afd032d",
|
"0x0010f94b296a852aaac52ea6c5ac72e03afd032d",
|
||||||
|
|
||||||
"0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A",
|
"0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A",
|
||||||
"0x00E6d2b931F55a3f1701c7389d592a7778897879",
|
"0x00E6d2b931F55a3f1701c7389d592a7778897879",
|
||||||
"0x00e4a10650e5a6D6001C38ff8E64F97016a1645c",
|
"0x00e4a10650e5a6D6001C38ff8E64F97016a1645c",
|
||||||
|
|
||||||
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
|
"0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"validateScoreTransition": 1000000,
|
"validateScoreTransition": 1000000,
|
||||||
"validateStepTransition": 1500000,
|
"validateStepTransition": 1500000,
|
||||||
"maximumUncleCount": 2
|
"maximumUncleCountTransition": 5067000,
|
||||||
|
"maximumUncleCount": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -38,7 +36,11 @@
|
|||||||
"forkCanonHash": "0x0a66d93c2f727dca618fabaf70c39b37018c73d78b939d8b11efbbd09034778f",
|
"forkCanonHash": "0x0a66d93c2f727dca618fabaf70c39b37018c73d78b939d8b11efbbd09034778f",
|
||||||
"validateReceiptsTransition" : 1000000,
|
"validateReceiptsTransition" : 1000000,
|
||||||
"eip155Transition": 1000000,
|
"eip155Transition": 1000000,
|
||||||
"validateChainIdTransition": 1000000
|
"validateChainIdTransition": 1000000,
|
||||||
|
"eip140Transition": 5067000,
|
||||||
|
"eip211Transition": 5067000,
|
||||||
|
"eip214Transition": 5067000,
|
||||||
|
"eip658Transition": 5067000
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
@ -55,13 +57,17 @@
|
|||||||
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
"0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
"0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
"0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
|
"0x0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 5067000, "pricing": { "modexp": { "divisor": 20 } } } },
|
||||||
|
"0x0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 5067000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||||
|
"0x0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 5067000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
|
||||||
|
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 5067000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
|
||||||
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
|
"0x00521965e7bd230323c423d96c657db5b79d099f": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
|
||||||
},
|
},
|
||||||
"nodes": [
|
"nodes": [
|
||||||
"enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303",
|
"enode://56abaf065581a5985b8c5f4f88bd202526482761ba10be9bfdcd14846dd01f652ec33fde0f8c0fd1db19b59a4c04465681fcef50e11380ca88d25996191c52de@40.71.221.215:30303",
|
||||||
"enode://dcf984764db421fa0cd8dc7fc02ae378545723abb94d179f55325514cc30185eaea3dcefde6e358b7cdbe970c50b7c49e841618713a9a72d6f3f59ad9949ec6b@52.165.239.18:30303",
|
"enode://d07827483dc47b368eaf88454fb04b41b7452cf454e194e2bd4c14f98a3278fed5d819dbecd0d010407fc7688d941ee1e58d4f9c6354d3da3be92f55c17d7ce3@52.166.117.77:30303",
|
||||||
|
"enode://8fa162563a8e5a05eef3e1cd5abc5828c71344f7277bb788a395cce4a0e30baf2b34b92fe0b2dbbba2313ee40236bae2aab3c9811941b9f5a7e8e90aaa27ecba@52.165.239.18:30303",
|
||||||
"enode://7e2e7f00784f516939f94e22bdc6cf96153603ca2b5df1c7cc0f90a38e7a2f218ffb1c05b156835e8b49086d11fdd1b3e2965be16baa55204167aa9bf536a4d9@52.243.47.56:30303",
|
"enode://7e2e7f00784f516939f94e22bdc6cf96153603ca2b5df1c7cc0f90a38e7a2f218ffb1c05b156835e8b49086d11fdd1b3e2965be16baa55204167aa9bf536a4d9@52.243.47.56:30303",
|
||||||
"enode://d51b3e98bf35addf2f1d0ea1ffc90483e24d7c60b0fb3be1701e818f3d6778c06e53fdec737a534fe222956296f9d6e909baa025916a94601897e5c7136a7d95@40.71.221.215:30303",
|
"enode://0518a3d35d4a7b3e8c433e7ffd2355d84a1304ceb5ef349787b556197f0c87fad09daed760635b97d52179d645d3e6d16a37d2cc0a9945c2ddf585684beb39ac@40.68.248.100:30303"
|
||||||
"enode://419d42e300e8fd379ff6d045d93d7e66a091441e7b3c9f1d3d10088d8634ad37721e6bf86148f78c3f1b9f1360dc566ca8ee830b2d2079bc9f7171ea6152bb64@52.166.117.77:30303"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit d6185ea16eaba7ff685c069c2064819f9549c4d7
|
Subproject commit d9d6133c1bc5dca4c74c9eb758a39546a0d46b45
|
@ -22,7 +22,6 @@ pub type LogBloom = ::log_entry::LogBloom;
|
|||||||
/// Constant 2048-bit datum for 0. Often used as a default.
|
/// Constant 2048-bit datum for 0. Often used as a default.
|
||||||
pub static ZERO_LOGBLOOM: LogBloom = ::bigint::hash::H2048([0x00; 256]);
|
pub static ZERO_LOGBLOOM: LogBloom = ::bigint::hash::H2048([0x00; 256]);
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
|
||||||
/// Semantic boolean for when a seal/signature is included.
|
/// Semantic boolean for when a seal/signature is included.
|
||||||
pub enum Seal {
|
pub enum Seal {
|
||||||
/// The seal/signature is included.
|
/// The seal/signature is included.
|
||||||
|
@ -301,7 +301,6 @@ pub struct SealedBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'x> OpenBlock<'x> {
|
impl<'x> OpenBlock<'x> {
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
/// Create a new `OpenBlock` ready for transaction pushing.
|
/// Create a new `OpenBlock` ready for transaction pushing.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine: &'x EthEngine,
|
engine: &'x EthEngine,
|
||||||
@ -380,8 +379,13 @@ impl<'x> OpenBlock<'x> {
|
|||||||
/// NOTE Will check chain constraints and the uncle number but will NOT check
|
/// NOTE Will check chain constraints and the uncle number but will NOT check
|
||||||
/// that the header itself is actually valid.
|
/// that the header itself is actually valid.
|
||||||
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
|
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
|
||||||
if self.block.uncles.len() + 1 > self.engine.maximum_uncle_count() {
|
let max_uncles = self.engine.maximum_uncle_count(self.block.header().number());
|
||||||
return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.uncles.len() + 1}));
|
if self.block.uncles.len() + 1 > max_uncles {
|
||||||
|
return Err(BlockError::TooManyUncles(OutOfBounds{
|
||||||
|
min: None,
|
||||||
|
max: Some(max_uncles),
|
||||||
|
found: self.block.uncles.len() + 1,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
// TODO: check number
|
// TODO: check number
|
||||||
// TODO: check not a direct ancestor (use last_hashes for that)
|
// TODO: check not a direct ancestor (use last_hashes for that)
|
||||||
@ -609,7 +613,6 @@ impl IsBlock for SealedBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by block header, transactions and uncles
|
/// Enact the block given by block header, transactions and uncles
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
pub fn enact(
|
pub fn enact(
|
||||||
header: &Header,
|
header: &Header,
|
||||||
transactions: &[SignedTransaction],
|
transactions: &[SignedTransaction],
|
||||||
@ -683,7 +686,6 @@ fn push_transactions(block: &mut OpenBlock, transactions: &[SignedTransaction])
|
|||||||
|
|
||||||
// TODO [ToDr] Pass `PreverifiedBlock` by move, this will avoid unecessary allocation
|
// TODO [ToDr] Pass `PreverifiedBlock` by move, this will avoid unecessary allocation
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
pub fn enact_verified(
|
pub fn enact_verified(
|
||||||
block: &PreverifiedBlock,
|
block: &PreverifiedBlock,
|
||||||
engine: &EthEngine,
|
engine: &EthEngine,
|
||||||
@ -726,7 +728,6 @@ mod tests {
|
|||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
fn enact_bytes(
|
fn enact_bytes(
|
||||||
block_bytes: &[u8],
|
block_bytes: &[u8],
|
||||||
engine: &EthEngine,
|
engine: &EthEngine,
|
||||||
@ -773,7 +774,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
fn enact_and_seal(
|
fn enact_and_seal(
|
||||||
block_bytes: &[u8],
|
block_bytes: &[u8],
|
||||||
engine: &EthEngine,
|
engine: &EthEngine,
|
||||||
|
@ -970,7 +970,6 @@ impl BlockChain {
|
|||||||
self.cache_man.lock().note_used(CacheId::BlockDetails(block_hash));
|
self.cache_man.lock().note_used(CacheId::BlockDetails(block_hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(similar_names))]
|
|
||||||
/// Inserts the block into backing cache database.
|
/// Inserts the block into backing cache database.
|
||||||
/// Expects the block to be valid and already verified.
|
/// Expects the block to be valid and already verified.
|
||||||
/// If the block is already known, does nothing.
|
/// If the block is already known, does nothing.
|
||||||
@ -1475,7 +1474,6 @@ impl BlockChain {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![cfg_attr(feature="dev", allow(similar_names))]
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rustc_hex::FromHex;
|
use rustc_hex::FromHex;
|
||||||
use hash::keccak;
|
use hash::keccak;
|
||||||
@ -1583,7 +1581,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
|
||||||
fn test_find_uncles() {
|
fn test_find_uncles() {
|
||||||
let mut canon_chain = ChainGenerator::default();
|
let mut canon_chain = ChainGenerator::default();
|
||||||
let mut finalizer = BlockFinalizer::default();
|
let mut finalizer = BlockFinalizer::default();
|
||||||
@ -1793,7 +1790,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
|
||||||
fn test_small_fork() {
|
fn test_small_fork() {
|
||||||
let mut canon_chain = ChainGenerator::default();
|
let mut canon_chain = ChainGenerator::default();
|
||||||
let mut finalizer = BlockFinalizer::default();
|
let mut finalizer = BlockFinalizer::default();
|
||||||
|
@ -1855,7 +1855,7 @@ impl MiningBlockChainClient for Client {
|
|||||||
let mut open_block = OpenBlock::new(
|
let mut open_block = OpenBlock::new(
|
||||||
engine,
|
engine,
|
||||||
self.factories.clone(),
|
self.factories.clone(),
|
||||||
false, // TODO: this will need to be parameterised once we want to do immediate mining insertion.
|
self.tracedb.read().tracing_enabled(),
|
||||||
self.state_db.lock().boxed_clone_canon(&h),
|
self.state_db.lock().boxed_clone_canon(&h),
|
||||||
best_header,
|
best_header,
|
||||||
self.build_last_hashes(h.clone()),
|
self.build_last_hashes(h.clone()),
|
||||||
@ -1870,7 +1870,7 @@ impl MiningBlockChainClient for Client {
|
|||||||
.find_uncle_headers(&h, engine.maximum_uncle_age())
|
.find_uncle_headers(&h, engine.maximum_uncle_age())
|
||||||
.unwrap_or_else(Vec::new)
|
.unwrap_or_else(Vec::new)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.take(engine.maximum_uncle_count())
|
.take(engine.maximum_uncle_count(open_block.header().number()))
|
||||||
.foreach(|h| {
|
.foreach(|h| {
|
||||||
open_block.push_uncle(h).expect("pushing maximum_uncle_count;
|
open_block.push_uncle(h).expect("pushing maximum_uncle_count;
|
||||||
open_block was just created;
|
open_block was just created;
|
||||||
@ -1885,7 +1885,7 @@ impl MiningBlockChainClient for Client {
|
|||||||
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
|
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
|
||||||
let engine = &*self.engine;
|
let engine = &*self.engine;
|
||||||
let mut block = block.reopen(engine);
|
let mut block = block.reopen(engine);
|
||||||
let max_uncles = engine.maximum_uncle_count();
|
let max_uncles = engine.maximum_uncle_count(block.header().number());
|
||||||
if block.uncles().len() < max_uncles {
|
if block.uncles().len() < max_uncles {
|
||||||
let chain = self.chain.read();
|
let chain = self.chain.read();
|
||||||
let h = chain.best_block_hash();
|
let h = chain.best_block_hash();
|
||||||
|
@ -51,8 +51,12 @@ mod finality;
|
|||||||
|
|
||||||
/// `AuthorityRound` params.
|
/// `AuthorityRound` params.
|
||||||
pub struct AuthorityRoundParams {
|
pub struct AuthorityRoundParams {
|
||||||
/// Time to wait before next block or authority switching.
|
/// Time to wait before next block or authority switching,
|
||||||
pub step_duration: Duration,
|
/// in seconds.
|
||||||
|
///
|
||||||
|
/// Deliberately typed as u16 as too high of a value leads
|
||||||
|
/// to slow block issuance.
|
||||||
|
pub step_duration: u16,
|
||||||
/// Starting step,
|
/// Starting step,
|
||||||
pub start_step: Option<u64>,
|
pub start_step: Option<u64>,
|
||||||
/// Valid validators.
|
/// Valid validators.
|
||||||
@ -65,20 +69,30 @@ pub struct AuthorityRoundParams {
|
|||||||
pub immediate_transitions: bool,
|
pub immediate_transitions: bool,
|
||||||
/// Block reward in base units.
|
/// Block reward in base units.
|
||||||
pub block_reward: U256,
|
pub block_reward: U256,
|
||||||
|
/// Number of accepted uncles transition block.
|
||||||
|
pub maximum_uncle_count_transition: u64,
|
||||||
/// Number of accepted uncles.
|
/// Number of accepted uncles.
|
||||||
pub maximum_uncle_count: usize,
|
pub maximum_uncle_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const U16_MAX: usize = ::std::u16::MAX as usize;
|
||||||
|
|
||||||
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||||
fn from(p: ethjson::spec::AuthorityRoundParams) -> Self {
|
fn from(p: ethjson::spec::AuthorityRoundParams) -> Self {
|
||||||
|
let mut step_duration_usize: usize = p.step_duration.into();
|
||||||
|
if step_duration_usize > U16_MAX {
|
||||||
|
step_duration_usize = U16_MAX;
|
||||||
|
warn!(target: "engine", "step_duration is too high ({}), setting it to {}", step_duration_usize, U16_MAX);
|
||||||
|
}
|
||||||
AuthorityRoundParams {
|
AuthorityRoundParams {
|
||||||
step_duration: Duration::from_secs(p.step_duration.into()),
|
step_duration: step_duration_usize as u16,
|
||||||
validators: new_validator_set(p.validators),
|
validators: new_validator_set(p.validators),
|
||||||
start_step: p.start_step.map(Into::into),
|
start_step: p.start_step.map(Into::into),
|
||||||
validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
|
validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
|
||||||
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
||||||
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
||||||
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
|
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
|
||||||
|
maximum_uncle_count_transition: p.maximum_uncle_count_transition.map_or(0, Into::into),
|
||||||
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,26 +103,47 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
|||||||
struct Step {
|
struct Step {
|
||||||
calibrate: bool, // whether calibration is enabled.
|
calibrate: bool, // whether calibration is enabled.
|
||||||
inner: AtomicUsize,
|
inner: AtomicUsize,
|
||||||
duration: Duration,
|
duration: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Step {
|
impl Step {
|
||||||
fn load(&self) -> usize { self.inner.load(AtomicOrdering::SeqCst) }
|
fn load(&self) -> usize { self.inner.load(AtomicOrdering::SeqCst) }
|
||||||
fn duration_remaining(&self) -> Duration {
|
fn duration_remaining(&self) -> Duration {
|
||||||
let now = unix_now();
|
let now = unix_now();
|
||||||
let step_end = self.duration * (self.load() as u32 + 1);
|
let expected_seconds = (self.load() as u64)
|
||||||
|
.checked_add(1)
|
||||||
|
.and_then(|ctr| ctr.checked_mul(self.duration as u64));
|
||||||
|
match expected_seconds {
|
||||||
|
Some(secs) => {
|
||||||
|
let step_end = Duration::from_secs(secs);
|
||||||
if step_end > now {
|
if step_end > now {
|
||||||
step_end - now
|
step_end - now
|
||||||
} else {
|
} else {
|
||||||
Duration::from_secs(0)
|
Duration::from_secs(0)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
let ctr = self.load();
|
||||||
|
error!(target: "engine", "Step counter is too high: {}, aborting", ctr);
|
||||||
|
panic!("step counter is too high: {}", ctr)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
fn increment(&self) {
|
fn increment(&self) {
|
||||||
self.inner.fetch_add(1, AtomicOrdering::SeqCst);
|
use std::usize;
|
||||||
|
// fetch_add won't panic on overflow but will rather wrap
|
||||||
|
// around, leading to zero as the step counter, which might
|
||||||
|
// lead to unexpected situations, so it's better to shut down.
|
||||||
|
if self.inner.fetch_add(1, AtomicOrdering::SeqCst) == usize::MAX {
|
||||||
|
error!(target: "engine", "Step counter is too high: {}, aborting", usize::MAX);
|
||||||
|
panic!("step counter is too high: {}", usize::MAX);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
fn calibrate(&self) {
|
fn calibrate(&self) {
|
||||||
if self.calibrate {
|
if self.calibrate {
|
||||||
let new_step = unix_now().as_secs() / self.duration.as_secs();
|
let new_step = unix_now().as_secs() / (self.duration as u64);
|
||||||
self.inner.store(new_step as usize, AtomicOrdering::SeqCst);
|
self.inner.store(new_step as usize, AtomicOrdering::SeqCst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,6 +158,11 @@ impl Step {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||||
|
fn calculate_score(parent_step: U256, current_step: U256) -> U256 {
|
||||||
|
U256::from(U128::max_value()) + parent_step - current_step
|
||||||
|
}
|
||||||
|
|
||||||
struct EpochManager {
|
struct EpochManager {
|
||||||
epoch_transition_hash: H256,
|
epoch_transition_hash: H256,
|
||||||
epoch_transition_number: BlockNumber,
|
epoch_transition_number: BlockNumber,
|
||||||
@ -221,6 +261,7 @@ pub struct AuthorityRound {
|
|||||||
epoch_manager: Mutex<EpochManager>,
|
epoch_manager: Mutex<EpochManager>,
|
||||||
immediate_transitions: bool,
|
immediate_transitions: bool,
|
||||||
block_reward: U256,
|
block_reward: U256,
|
||||||
|
maximum_uncle_count_transition: u64,
|
||||||
maximum_uncle_count: usize,
|
maximum_uncle_count: usize,
|
||||||
machine: EthereumMachine,
|
machine: EthereumMachine,
|
||||||
}
|
}
|
||||||
@ -350,8 +391,12 @@ impl AsMillis for Duration {
|
|||||||
impl AuthorityRound {
|
impl AuthorityRound {
|
||||||
/// Create a new instance of AuthorityRound engine.
|
/// Create a new instance of AuthorityRound engine.
|
||||||
pub fn new(our_params: AuthorityRoundParams, machine: EthereumMachine) -> Result<Arc<Self>, Error> {
|
pub fn new(our_params: AuthorityRoundParams, machine: EthereumMachine) -> Result<Arc<Self>, Error> {
|
||||||
|
if our_params.step_duration == 0 {
|
||||||
|
error!(target: "engine", "Authority Round step duration can't be zero, aborting");
|
||||||
|
panic!("authority_round: step duration can't be zero")
|
||||||
|
}
|
||||||
let should_timeout = our_params.start_step.is_none();
|
let should_timeout = our_params.start_step.is_none();
|
||||||
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / our_params.step_duration.as_secs())) as usize;
|
let initial_step = our_params.start_step.unwrap_or_else(|| (unix_now().as_secs() / (our_params.step_duration as u64))) as usize;
|
||||||
let engine = Arc::new(
|
let engine = Arc::new(
|
||||||
AuthorityRound {
|
AuthorityRound {
|
||||||
transition_service: IoService::<()>::start()?,
|
transition_service: IoService::<()>::start()?,
|
||||||
@ -369,6 +414,7 @@ impl AuthorityRound {
|
|||||||
epoch_manager: Mutex::new(EpochManager::blank()),
|
epoch_manager: Mutex::new(EpochManager::blank()),
|
||||||
immediate_transitions: our_params.immediate_transitions,
|
immediate_transitions: our_params.immediate_transitions,
|
||||||
block_reward: our_params.block_reward,
|
block_reward: our_params.block_reward,
|
||||||
|
maximum_uncle_count_transition: our_params.maximum_uncle_count_transition,
|
||||||
maximum_uncle_count: our_params.maximum_uncle_count,
|
maximum_uncle_count: our_params.maximum_uncle_count,
|
||||||
machine: machine,
|
machine: machine,
|
||||||
});
|
});
|
||||||
@ -441,15 +487,23 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maximum_uncle_count(&self) -> usize { self.maximum_uncle_count }
|
fn maximum_uncle_count(&self, block: BlockNumber) -> usize {
|
||||||
|
if block >= self.maximum_uncle_count_transition {
|
||||||
|
self.maximum_uncle_count
|
||||||
|
} else {
|
||||||
|
// fallback to default value
|
||||||
|
2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
let parent_step = header_step(parent).expect("Header has been verified; qed");
|
||||||
let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load().into();
|
let score = calculate_score(parent_step.into(), self.step.load().into());
|
||||||
header.set_difficulty(new_difficulty);
|
header.set_difficulty(score);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seals_internally(&self) -> Option<bool> {
|
fn seals_internally(&self) -> Option<bool> {
|
||||||
|
// TODO: accept a `&Call` here so we can query the validator set.
|
||||||
Some(self.signer.read().is_some())
|
Some(self.signer.read().is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,14 +511,23 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
///
|
///
|
||||||
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
||||||
/// `Seal::None` will be returned.
|
/// `Seal::None` will be returned.
|
||||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
fn generate_seal(&self, block: &ExecutedBlock, parent: &Header) -> Seal {
|
||||||
// first check to avoid generating signature most of the time
|
// first check to avoid generating signature most of the time
|
||||||
// (but there's still a race to the `compare_and_swap`)
|
// (but there's still a race to the `compare_and_swap`)
|
||||||
if !self.can_propose.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
if !self.can_propose.load(AtomicOrdering::SeqCst) { return Seal::None; }
|
||||||
|
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
|
let parent_step: U256 = header_step(parent)
|
||||||
|
.expect("Header has been verified; qed").into();
|
||||||
|
|
||||||
let step = self.step.load();
|
let step = self.step.load();
|
||||||
|
|
||||||
|
let expected_diff = calculate_score(parent_step, step.into());
|
||||||
|
|
||||||
|
if header.difficulty() != &expected_diff {
|
||||||
|
return Seal::None;
|
||||||
|
}
|
||||||
|
|
||||||
// fetch correct validator set for current epoch, taking into account
|
// fetch correct validator set for current epoch, taking into account
|
||||||
// finality of previous transitions.
|
// finality of previous transitions.
|
||||||
let active_set;
|
let active_set;
|
||||||
@ -491,6 +554,13 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if is_step_proposer(validators, header.parent_hash(), step, header.author()) {
|
if is_step_proposer(validators, header.parent_hash(), step, header.author()) {
|
||||||
|
// this is guarded against by `can_propose` unless the block was signed
|
||||||
|
// on the same step (implies same key) and on a different node.
|
||||||
|
if parent_step == step.into() {
|
||||||
|
warn!("Attempted to seal block on the same step as parent. Is this authority sealing with more than one node?");
|
||||||
|
return Seal::None;
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(signature) = self.sign(header.bare_hash()) {
|
if let Ok(signature) = self.sign(header.bare_hash()) {
|
||||||
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
|
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
|
||||||
|
|
||||||
@ -505,6 +575,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
trace!(target: "engine", "generate_seal: {} not a proposer for step {}.",
|
trace!(target: "engine", "generate_seal: {} not a proposer for step {}.",
|
||||||
header.author(), step);
|
header.author(), step);
|
||||||
}
|
}
|
||||||
|
|
||||||
Seal::None
|
Seal::None
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,7 +617,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check the number of seal fields.
|
/// Check the number of seal fields.
|
||||||
fn verify_block_basic(&self, header: &Header,) -> Result<(), Error> {
|
fn verify_block_basic(&self, header: &Header) -> Result<(), Error> {
|
||||||
if header.number() >= self.validate_score_transition && *header.difficulty() >= U256::from(U128::max_value()) {
|
if header.number() >= self.validate_score_transition && *header.difficulty() >= U256::from(U128::max_value()) {
|
||||||
Err(From::from(BlockError::DifficultyOutOfBounds(
|
Err(From::from(BlockError::DifficultyOutOfBounds(
|
||||||
OutOfBounds { min: None, max: Some(U256::from(U128::max_value())), found: *header.difficulty() }
|
OutOfBounds { min: None, max: Some(U256::from(U128::max_value())), found: *header.difficulty() }
|
||||||
@ -857,17 +928,51 @@ mod tests {
|
|||||||
let b2 = b2.close_and_lock();
|
let b2 = b2.close_and_lock();
|
||||||
|
|
||||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||||
if let Seal::Regular(seal) = engine.generate_seal(b1.block()) {
|
if let Seal::Regular(seal) = engine.generate_seal(b1.block(), &genesis_header) {
|
||||||
assert!(b1.clone().try_seal(engine, seal).is_ok());
|
assert!(b1.clone().try_seal(engine, seal).is_ok());
|
||||||
// Second proposal is forbidden.
|
// Second proposal is forbidden.
|
||||||
assert!(engine.generate_seal(b1.block()) == Seal::None);
|
assert!(engine.generate_seal(b1.block(), &genesis_header) == Seal::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.set_signer(tap, addr2, "2".into());
|
engine.set_signer(tap, addr2, "2".into());
|
||||||
if let Seal::Regular(seal) = engine.generate_seal(b2.block()) {
|
if let Seal::Regular(seal) = engine.generate_seal(b2.block(), &genesis_header) {
|
||||||
assert!(b2.clone().try_seal(engine, seal).is_ok());
|
assert!(b2.clone().try_seal(engine, seal).is_ok());
|
||||||
// Second proposal is forbidden.
|
// Second proposal is forbidden.
|
||||||
assert!(engine.generate_seal(b2.block()) == Seal::None);
|
assert!(engine.generate_seal(b2.block(), &genesis_header) == Seal::None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checks_difficulty_in_generate_seal() {
|
||||||
|
let tap = Arc::new(AccountProvider::transient_provider());
|
||||||
|
let addr1 = tap.insert_account(keccak("1").into(), "1").unwrap();
|
||||||
|
let addr2 = tap.insert_account(keccak("0").into(), "0").unwrap();
|
||||||
|
|
||||||
|
let spec = Spec::new_test_round();
|
||||||
|
let engine = &*spec.engine;
|
||||||
|
|
||||||
|
let genesis_header = spec.genesis_header();
|
||||||
|
let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
|
let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();
|
||||||
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
|
|
||||||
|
let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
|
let b1 = b1.close_and_lock();
|
||||||
|
let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
|
let b2 = b2.close_and_lock();
|
||||||
|
|
||||||
|
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||||
|
match engine.generate_seal(b1.block(), &genesis_header) {
|
||||||
|
Seal::None | Seal::Proposal(_) => panic!("wrong seal"),
|
||||||
|
Seal::Regular(_) => {
|
||||||
|
engine.step();
|
||||||
|
|
||||||
|
engine.set_signer(tap.clone(), addr2, "0".into());
|
||||||
|
match engine.generate_seal(b2.block(), &genesis_header) {
|
||||||
|
Seal::Regular(_) | Seal::Proposal(_) => panic!("sealed despite wrong difficulty"),
|
||||||
|
Seal::None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,12 +1055,13 @@ mod tests {
|
|||||||
fn reports_skipped() {
|
fn reports_skipped() {
|
||||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||||
let params = AuthorityRoundParams {
|
let params = AuthorityRoundParams {
|
||||||
step_duration: Default::default(),
|
step_duration: 1,
|
||||||
start_step: Some(1),
|
start_step: Some(1),
|
||||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||||
validate_score_transition: 0,
|
validate_score_transition: 0,
|
||||||
validate_step_transition: 0,
|
validate_step_transition: 0,
|
||||||
immediate_transitions: true,
|
immediate_transitions: true,
|
||||||
|
maximum_uncle_count_transition: 0,
|
||||||
maximum_uncle_count: 0,
|
maximum_uncle_count: 0,
|
||||||
block_reward: Default::default(),
|
block_reward: Default::default(),
|
||||||
};
|
};
|
||||||
@ -984,4 +1090,77 @@ mod tests {
|
|||||||
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
||||||
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_uncles_transition() {
|
||||||
|
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||||
|
let params = AuthorityRoundParams {
|
||||||
|
step_duration: 1,
|
||||||
|
start_step: Some(1),
|
||||||
|
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||||
|
validate_score_transition: 0,
|
||||||
|
validate_step_transition: 0,
|
||||||
|
immediate_transitions: true,
|
||||||
|
maximum_uncle_count_transition: 1,
|
||||||
|
maximum_uncle_count: 0,
|
||||||
|
block_reward: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let aura = {
|
||||||
|
let mut c_params = ::spec::CommonParams::default();
|
||||||
|
c_params.gas_limit_bound_divisor = 5.into();
|
||||||
|
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
||||||
|
AuthorityRound::new(params, machine).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(aura.maximum_uncle_count(0), 2);
|
||||||
|
assert_eq!(aura.maximum_uncle_count(1), 0);
|
||||||
|
assert_eq!(aura.maximum_uncle_count(100), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected="counter is too high")]
|
||||||
|
fn test_counter_increment_too_high() {
|
||||||
|
use super::Step;
|
||||||
|
let step = Step {
|
||||||
|
calibrate: false,
|
||||||
|
inner: AtomicUsize::new(::std::usize::MAX),
|
||||||
|
duration: 1,
|
||||||
|
};
|
||||||
|
step.increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected="counter is too high")]
|
||||||
|
fn test_counter_duration_remaining_too_high() {
|
||||||
|
use super::Step;
|
||||||
|
let step = Step {
|
||||||
|
calibrate: false,
|
||||||
|
inner: AtomicUsize::new(::std::usize::MAX),
|
||||||
|
duration: 1,
|
||||||
|
};
|
||||||
|
step.duration_remaining();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected="authority_round: step duration can't be zero")]
|
||||||
|
fn test_step_duration_zero() {
|
||||||
|
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||||
|
let params = AuthorityRoundParams {
|
||||||
|
step_duration: 0,
|
||||||
|
start_step: Some(1),
|
||||||
|
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||||
|
validate_score_transition: 0,
|
||||||
|
validate_step_transition: 0,
|
||||||
|
immediate_transitions: true,
|
||||||
|
maximum_uncle_count_transition: 0,
|
||||||
|
maximum_uncle_count: 0,
|
||||||
|
block_reward: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut c_params = ::spec::CommonParams::default();
|
||||||
|
c_params.gas_limit_bound_divisor = 5.into();
|
||||||
|
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
||||||
|
AuthorityRound::new(params, machine).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ impl Engine<EthereumMachine> for BasicAuthority {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to seal the block internally.
|
/// Attempt to seal the block internally.
|
||||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
let author = header.author();
|
let author = header.author();
|
||||||
if self.validators.contains(header.parent_hash(), author) {
|
if self.validators.contains(header.parent_hash(), author) {
|
||||||
@ -251,7 +251,7 @@ mod tests {
|
|||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
if let Seal::Regular(seal) = engine.generate_seal(b.block()) {
|
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) {
|
||||||
assert!(b.try_seal(engine, seal).is_ok());
|
assert!(b.try_seal(engine, seal).is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ impl<M: Machine> Engine<M> for InstantSeal<M>
|
|||||||
|
|
||||||
fn seals_internally(&self) -> Option<bool> { Some(true) }
|
fn seals_internally(&self) -> Option<bool> { Some(true) }
|
||||||
|
|
||||||
fn generate_seal(&self, block: &M::LiveBlock) -> Seal {
|
fn generate_seal(&self, block: &M::LiveBlock, _parent: &M::Header) -> Seal {
|
||||||
if block.transactions().is_empty() { Seal::None } else { Seal::Regular(Vec::new()) }
|
if block.transactions().is_empty() { Seal::None } else { Seal::Regular(Vec::new()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ mod tests {
|
|||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
if let Seal::Regular(seal) = engine.generate_seal(b.block()) {
|
if let Seal::Regular(seal) = engine.generate_seal(b.block(), &genesis_header) {
|
||||||
assert!(b.try_seal(engine, seal).is_ok());
|
assert!(b.try_seal(engine, seal).is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,8 @@ pub trait Engine<M: Machine>: Sync + Send {
|
|||||||
fn extra_info(&self, _header: &M::Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
fn extra_info(&self, _header: &M::Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
||||||
|
|
||||||
/// Maximum number of uncles a block is allowed to declare.
|
/// Maximum number of uncles a block is allowed to declare.
|
||||||
fn maximum_uncle_count(&self) -> usize { 0 }
|
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||||
|
|
||||||
/// The number of generations back that uncles can be.
|
/// The number of generations back that uncles can be.
|
||||||
fn maximum_uncle_age(&self) -> usize { 6 }
|
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||||
|
|
||||||
@ -225,7 +226,7 @@ pub trait Engine<M: Machine>: Sync + Send {
|
|||||||
///
|
///
|
||||||
/// It is fine to require access to state or a full client for this function, since
|
/// It is fine to require access to state or a full client for this function, since
|
||||||
/// light clients do not generate seals.
|
/// light clients do not generate seals.
|
||||||
fn generate_seal(&self, _block: &M::LiveBlock) -> Seal { Seal::None }
|
fn generate_seal(&self, _block: &M::LiveBlock, _parent: &M::Header) -> Seal { Seal::None }
|
||||||
|
|
||||||
/// Verify a locally-generated seal of a header.
|
/// Verify a locally-generated seal of a header.
|
||||||
///
|
///
|
||||||
@ -363,7 +364,7 @@ pub trait EthEngine: Engine<::machine::EthereumMachine> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The nonce with which accounts begin at given block.
|
/// The nonce with which accounts begin at given block.
|
||||||
fn account_start_nonce(&self, block: u64) -> U256 {
|
fn account_start_nonce(&self, block: BlockNumber) -> U256 {
|
||||||
self.machine().account_start_nonce(block)
|
self.machine().account_start_nonce(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
use bigint::prelude::U256;
|
use bigint::prelude::U256;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
|
use header::BlockNumber;
|
||||||
use parity_machine::{Header, LiveBlock, WithBalances};
|
use parity_machine::{Header, LiveBlock, WithBalances};
|
||||||
|
|
||||||
/// Params for a null engine.
|
/// Params for a null engine.
|
||||||
@ -95,7 +96,7 @@ impl<M: WithBalances> Engine<M> for NullEngine<M> {
|
|||||||
self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards)
|
self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||||
|
|
||||||
fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> {
|
fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -450,7 +450,7 @@ impl Engine<EthereumMachine> for Tendermint {
|
|||||||
|
|
||||||
fn machine(&self) -> &EthereumMachine { &self.machine }
|
fn machine(&self) -> &EthereumMachine { &self.machine }
|
||||||
|
|
||||||
fn maximum_uncle_count(&self) -> usize { 0 }
|
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||||
|
|
||||||
fn maximum_uncle_age(&self) -> usize { 0 }
|
fn maximum_uncle_age(&self) -> usize { 0 }
|
||||||
|
|
||||||
@ -483,7 +483,7 @@ impl Engine<EthereumMachine> for Tendermint {
|
|||||||
///
|
///
|
||||||
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
/// This operation is synchronous and may (quite reasonably) not be available, in which case
|
||||||
/// `Seal::None` will be returned.
|
/// `Seal::None` will be returned.
|
||||||
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
|
fn generate_seal(&self, block: &ExecutedBlock, _parent: &Header) -> Seal {
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
let author = header.author();
|
let author = header.author();
|
||||||
// Only proposer can generate seal if None was generated.
|
// Only proposer can generate seal if None was generated.
|
||||||
@ -805,7 +805,7 @@ mod tests {
|
|||||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||||
let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
let b = OpenBlock::new(spec.engine.as_ref(), Default::default(), false, db.boxed_clone(), &genesis_header, last_hashes, proposer, (3141562.into(), 31415620.into()), vec![], false).unwrap();
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
if let Seal::Proposal(seal) = spec.engine.generate_seal(b.block()) {
|
if let Seal::Proposal(seal) = spec.engine.generate_seal(b.block(), &genesis_header) {
|
||||||
(b, seal)
|
(b, seal)
|
||||||
} else {
|
} else {
|
||||||
panic!()
|
panic!()
|
||||||
|
@ -58,7 +58,7 @@ impl ValidatorContract {
|
|||||||
let client = self.client.read().clone();
|
let client = self.client.read().clone();
|
||||||
Box::new(move |a, d| client.as_ref()
|
Box::new(move |a, d| client.as_ref()
|
||||||
.and_then(Weak::upgrade)
|
.and_then(Weak::upgrade)
|
||||||
.ok_or("No client!".into())
|
.ok_or_else(|| "No client!".into())
|
||||||
.and_then(|c| {
|
.and_then(|c| {
|
||||||
match c.as_full_client() {
|
match c.as_full_client() {
|
||||||
Some(c) => c.transact_contract(a, d)
|
Some(c) => c.transact_contract(a, d)
|
||||||
|
@ -138,7 +138,7 @@ impl ValidatorSet for Multi {
|
|||||||
}
|
}
|
||||||
*self.block_number.write() = Box::new(move |id| client
|
*self.block_number.write() = Box::new(move |id| client
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.ok_or("No client!".into())
|
.ok_or_else(|| "No client!".into())
|
||||||
.and_then(|c| c.block_number(id).ok_or("Unknown block".into())));
|
.and_then(|c| c.block_number(id).ok_or("Unknown block".into())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ impl ValidatorSet for ValidatorSafeContract {
|
|||||||
let client = self.client.read().clone();
|
let client = self.client.read().clone();
|
||||||
Box::new(move |addr, data| client.as_ref()
|
Box::new(move |addr, data| client.as_ref()
|
||||||
.and_then(Weak::upgrade)
|
.and_then(Weak::upgrade)
|
||||||
.ok_or("No client!".into())
|
.ok_or_else(|| "No client!".into())
|
||||||
.and_then(|c| {
|
.and_then(|c| {
|
||||||
match c.as_full_client() {
|
match c.as_full_client() {
|
||||||
Some(c) => c.call_contract(id, addr, data),
|
Some(c) => c.call_contract(id, addr, data),
|
||||||
|
@ -26,7 +26,7 @@ use util::Address;
|
|||||||
use unexpected::{OutOfBounds, Mismatch};
|
use unexpected::{OutOfBounds, Mismatch};
|
||||||
use block::*;
|
use block::*;
|
||||||
use error::{BlockError, Error};
|
use error::{BlockError, Error};
|
||||||
use header::Header;
|
use header::{Header, BlockNumber};
|
||||||
use engines::{self, Engine};
|
use engines::{self, Engine};
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use rlp::{self, UntrustedRlp};
|
use rlp::{self, UntrustedRlp};
|
||||||
@ -181,7 +181,7 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||||
|
|
||||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||||
let difficulty = self.calculate_difficulty(header, parent);
|
let difficulty = self.calculate_difficulty(header, parent);
|
||||||
@ -336,7 +336,6 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
|
||||||
impl Ethash {
|
impl Ethash {
|
||||||
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
|
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
|
||||||
const EXP_DIFF_PERIOD: u64 = 100_000;
|
const EXP_DIFF_PERIOD: u64 = 100_000;
|
||||||
|
@ -75,6 +75,11 @@ pub fn new_musicoin<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
|||||||
load(params.into(), include_bytes!("../../res/ethereum/musicoin.json"))
|
load(params.into(), include_bytes!("../../res/ethereum/musicoin.json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new Ellaism mainnet chain spec.
|
||||||
|
pub fn new_ellaism<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||||
|
load(params.into(), include_bytes!("../../res/ethereum/ellaism.json"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new Kovan testnet chain spec.
|
/// Create a new Kovan testnet chain spec.
|
||||||
pub fn new_kovan<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
pub fn new_kovan<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
|
||||||
load(params.into(), include_bytes!("../../res/ethereum/kovan.json"))
|
load(params.into(), include_bytes!("../../res/ethereum/kovan.json"))
|
||||||
|
@ -85,7 +85,6 @@ impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B>
|
|||||||
where T: Tracer, V: VMTracer, B: StateBackend
|
where T: Tracer, V: VMTracer, B: StateBackend
|
||||||
{
|
{
|
||||||
/// Basic `Externalities` constructor.
|
/// Basic `Externalities` constructor.
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
pub fn new(state: &'a mut State<B>,
|
pub fn new(state: &'a mut State<B>,
|
||||||
env_info: &'a EnvInfo,
|
env_info: &'a EnvInfo,
|
||||||
machine: &'a Machine,
|
machine: &'a Machine,
|
||||||
@ -302,7 +301,6 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
|||||||
Ok(self.state.code_size(address)?.unwrap_or(0))
|
Ok(self.state.code_size(address)?.unwrap_or(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(match_ref_pats))]
|
|
||||||
fn ret(mut self, gas: &U256, data: &ReturnData, apply_state: bool) -> vm::Result<U256>
|
fn ret(mut self, gas: &U256, data: &ReturnData, apply_state: bool) -> vm::Result<U256>
|
||||||
where Self: Sized {
|
where Self: Sized {
|
||||||
let handle_copy = |to: &mut Option<&mut Bytes>| {
|
let handle_copy = |to: &mut Option<&mut Bytes>| {
|
||||||
|
@ -16,23 +16,6 @@
|
|||||||
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![cfg_attr(feature="benches", feature(test))]
|
#![cfg_attr(feature="benches", feature(test))]
|
||||||
#![cfg_attr(feature="dev", feature(plugin))]
|
|
||||||
#![cfg_attr(feature="dev", plugin(clippy))]
|
|
||||||
|
|
||||||
// Clippy settings
|
|
||||||
// Most of the time much more readable
|
|
||||||
#![cfg_attr(feature="dev", allow(needless_range_loop))]
|
|
||||||
// Shorter than if-else
|
|
||||||
#![cfg_attr(feature="dev", allow(match_bool))]
|
|
||||||
// Keeps consistency (all lines with `.clone()`).
|
|
||||||
#![cfg_attr(feature="dev", allow(clone_on_copy))]
|
|
||||||
// Complains on Box<E> when implementing From<Box<E>>
|
|
||||||
#![cfg_attr(feature="dev", allow(boxed_local))]
|
|
||||||
// Complains about nested modules with same name as parent
|
|
||||||
#![cfg_attr(feature="dev", allow(module_inception))]
|
|
||||||
// TODO [todr] a lot of warnings to be fixed
|
|
||||||
#![cfg_attr(feature="dev", allow(assign_op_pattern))]
|
|
||||||
|
|
||||||
|
|
||||||
//! Ethcore library
|
//! Ethcore library
|
||||||
//!
|
//!
|
||||||
|
@ -366,7 +366,6 @@ impl Miner {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(match_same_arms))]
|
|
||||||
/// Prepares new block for sealing including top transactions from queue.
|
/// Prepares new block for sealing including top transactions from queue.
|
||||||
fn prepare_block(&self, chain: &MiningBlockChainClient) -> (ClosedBlock, Option<H256>) {
|
fn prepare_block(&self, chain: &MiningBlockChainClient) -> (ClosedBlock, Option<H256>) {
|
||||||
let _timer = PerfTimer::new("prepare_block");
|
let _timer = PerfTimer::new("prepare_block");
|
||||||
@ -534,7 +533,13 @@ impl Miner {
|
|||||||
fn seal_and_import_block_internally(&self, chain: &MiningBlockChainClient, block: ClosedBlock) -> bool {
|
fn seal_and_import_block_internally(&self, chain: &MiningBlockChainClient, block: ClosedBlock) -> bool {
|
||||||
if !block.transactions().is_empty() || self.forced_sealing() || Instant::now() > *self.next_mandatory_reseal.read() {
|
if !block.transactions().is_empty() || self.forced_sealing() || Instant::now() > *self.next_mandatory_reseal.read() {
|
||||||
trace!(target: "miner", "seal_block_internally: attempting internal seal.");
|
trace!(target: "miner", "seal_block_internally: attempting internal seal.");
|
||||||
match self.engine.generate_seal(block.block()) {
|
|
||||||
|
let parent_header = match chain.block_header(BlockId::Hash(*block.header().parent_hash())) {
|
||||||
|
Some(hdr) => hdr.decode(),
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.engine.generate_seal(block.block(), &parent_header) {
|
||||||
// Save proposal for later seal submission and broadcast it.
|
// Save proposal for later seal submission and broadcast it.
|
||||||
Seal::Proposal(seal) => {
|
Seal::Proposal(seal) => {
|
||||||
trace!(target: "miner", "Received a Proposal seal.");
|
trace!(target: "miner", "Received a Proposal seal.");
|
||||||
@ -702,8 +707,6 @@ impl Miner {
|
|||||||
/// Are we allowed to do a non-mandatory reseal?
|
/// Are we allowed to do a non-mandatory reseal?
|
||||||
fn tx_reseal_allowed(&self) -> bool { Instant::now() > *self.next_allowed_reseal.lock() }
|
fn tx_reseal_allowed(&self) -> bool { Instant::now() > *self.next_allowed_reseal.lock() }
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
|
||||||
#[cfg_attr(feature="dev", allow(redundant_closure))]
|
|
||||||
fn from_pending_block<H, F, G>(&self, latest_block_number: BlockNumber, from_chain: F, map_block: G) -> H
|
fn from_pending_block<H, F, G>(&self, latest_block_number: BlockNumber, from_chain: F, map_block: G) -> H
|
||||||
where F: Fn() -> H, G: FnOnce(&ClosedBlock) -> H {
|
where F: Fn() -> H, G: FnOnce(&ClosedBlock) -> H {
|
||||||
let sealing_work = self.sealing_work.lock();
|
let sealing_work = self.sealing_work.lock();
|
||||||
@ -863,7 +866,6 @@ impl MinerService for Miner {
|
|||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(collapsible_if))]
|
|
||||||
fn import_own_transaction(
|
fn import_own_transaction(
|
||||||
&self,
|
&self,
|
||||||
chain: &MiningBlockChainClient,
|
chain: &MiningBlockChainClient,
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![cfg_attr(all(nightly, feature="dev"), feature(plugin))]
|
|
||||||
#![cfg_attr(all(nightly, feature="dev"), plugin(clippy))]
|
|
||||||
|
|
||||||
//! Miner module
|
//! Miner module
|
||||||
//! Keeps track of transactions and mined block.
|
//! Keeps track of transactions and mined block.
|
||||||
|
@ -136,7 +136,6 @@ impl PartialOrd for TransactionOrigin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ord for TransactionOrigin {
|
impl Ord for TransactionOrigin {
|
||||||
#[cfg_attr(feature="dev", allow(match_same_arms))]
|
|
||||||
fn cmp(&self, other: &TransactionOrigin) -> Ordering {
|
fn cmp(&self, other: &TransactionOrigin) -> Ordering {
|
||||||
if *other == *self {
|
if *other == *self {
|
||||||
return Ordering::Equal;
|
return Ordering::Equal;
|
||||||
@ -516,7 +515,6 @@ pub struct AccountDetails {
|
|||||||
const GAS_PRICE_BUMP_SHIFT: usize = 3; // 2 = 25%, 3 = 12.5%, 4 = 6.25%
|
const GAS_PRICE_BUMP_SHIFT: usize = 3; // 2 = 25%, 3 = 12.5%, 4 = 6.25%
|
||||||
|
|
||||||
/// Describes the strategy used to prioritize transactions in the queue.
|
/// Describes the strategy used to prioritize transactions in the queue.
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum PrioritizationStrategy {
|
pub enum PrioritizationStrategy {
|
||||||
/// Use only gas price. Disregards the actual computation cost of the transaction.
|
/// Use only gas price. Disregards the actual computation cost of the transaction.
|
||||||
|
@ -186,7 +186,6 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(single_match))]
|
|
||||||
fn message(&self, _io: &IoContext<ClientIoMessage>, net_message: &ClientIoMessage) {
|
fn message(&self, _io: &IoContext<ClientIoMessage>, net_message: &ClientIoMessage) {
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
@ -57,7 +57,6 @@ impl StateProducer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(let_and_return))]
|
|
||||||
/// Tick the state producer. This alters the state, writing new data into
|
/// Tick the state producer. This alters the state, writing new data into
|
||||||
/// the database.
|
/// the database.
|
||||||
pub fn tick<R: Rng>(&mut self, rng: &mut R, db: &mut HashDB) {
|
pub fn tick<R: Rng>(&mut self, rng: &mut R, db: &mut HashDB) {
|
||||||
|
@ -35,6 +35,15 @@ use std::cell::{RefCell, Cell};
|
|||||||
|
|
||||||
const STORAGE_CACHE_ITEMS: usize = 8192;
|
const STORAGE_CACHE_ITEMS: usize = 8192;
|
||||||
|
|
||||||
|
/// Boolean type for clean/dirty status.
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
|
pub enum Filth {
|
||||||
|
/// Data has not been changed.
|
||||||
|
Clean,
|
||||||
|
/// Data has been changed.
|
||||||
|
Dirty,
|
||||||
|
}
|
||||||
|
|
||||||
/// Single account in the system.
|
/// Single account in the system.
|
||||||
/// Keeps track of changes to the code and storage.
|
/// Keeps track of changes to the code and storage.
|
||||||
/// The changes are applied in `commit_storage` and `commit_code`
|
/// The changes are applied in `commit_storage` and `commit_code`
|
||||||
|
@ -604,7 +604,6 @@ impl<B: Backend> State<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add `incr` to the balance of account `a`.
|
/// Add `incr` to the balance of account `a`.
|
||||||
#[cfg_attr(feature="dev", allow(single_match))]
|
|
||||||
pub fn add_balance(&mut self, a: &Address, incr: &U256, cleanup_mode: CleanupMode) -> trie::Result<()> {
|
pub fn add_balance(&mut self, a: &Address, incr: &U256, cleanup_mode: CleanupMode) -> trie::Result<()> {
|
||||||
trace!(target: "state", "add_balance({}, {}): {}", a, incr, self.balance(a)?);
|
trace!(target: "state", "add_balance({}, {}): {}", a, incr, self.balance(a)?);
|
||||||
let is_value_transfer = !incr.is_zero();
|
let is_value_transfer = !incr.is_zero();
|
||||||
@ -744,8 +743,6 @@ impl<B: Backend> State<B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Commits our cached account changes into the trie.
|
/// Commits our cached account changes into the trie.
|
||||||
#[cfg_attr(feature="dev", allow(match_ref_pats))]
|
|
||||||
#[cfg_attr(feature="dev", allow(needless_borrow))]
|
|
||||||
pub fn commit(&mut self) -> Result<(), Error> {
|
pub fn commit(&mut self) -> Result<(), Error> {
|
||||||
// first, commit the sub trees.
|
// first, commit the sub trees.
|
||||||
let mut accounts = self.cache.borrow_mut();
|
let mut accounts = self.cache.borrow_mut();
|
||||||
|
@ -58,7 +58,6 @@ impl Substate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the cleanup mode object from this.
|
/// Get the cleanup mode object from this.
|
||||||
#[cfg_attr(feature="dev", allow(wrong_self_convention))]
|
|
||||||
pub fn to_cleanup_mode(&mut self, schedule: &Schedule) -> CleanupMode {
|
pub fn to_cleanup_mode(&mut self, schedule: &Schedule) -> CleanupMode {
|
||||||
match (schedule.kill_dust != CleanDustMode::Off, schedule.no_empty, schedule.kill_empty) {
|
match (schedule.kill_dust != CleanDustMode::Off, schedule.no_empty, schedule.kill_empty) {
|
||||||
(false, false, _) => CleanupMode::ForceCreate,
|
(false, false, _) => CleanupMode::ForceCreate,
|
||||||
|
@ -427,7 +427,6 @@ impl state::Backend for StateDB {
|
|||||||
cache.accounts.get_mut(addr).map(|a| a.as_ref().map(|a| a.clone_basic()))
|
cache.accounts.get_mut(addr).map(|a| a.as_ref().map(|a| a.clone_basic()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(map_clone))]
|
|
||||||
fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>> {
|
fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>> {
|
||||||
let mut cache = self.code_cache.lock();
|
let mut cache = self.code_cache.lock();
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ use cache_manager::CacheManager;
|
|||||||
const TRACE_DB_VER: &'static [u8] = b"1.0";
|
const TRACE_DB_VER: &'static [u8] = b"1.0";
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
|
||||||
enum TraceDBIndex {
|
enum TraceDBIndex {
|
||||||
/// Block traces index.
|
/// Block traces index.
|
||||||
BlockTraces = 0,
|
BlockTraces = 0,
|
||||||
|
@ -164,7 +164,6 @@ struct QueueSignal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl QueueSignal {
|
impl QueueSignal {
|
||||||
#[cfg_attr(feature="dev", allow(bool_comparison))]
|
|
||||||
fn set_sync(&self) {
|
fn set_sync(&self) {
|
||||||
// Do not signal when we are about to close
|
// Do not signal when we are about to close
|
||||||
if self.deleting.load(AtomicOrdering::Relaxed) {
|
if self.deleting.load(AtomicOrdering::Relaxed) {
|
||||||
@ -179,7 +178,6 @@ impl QueueSignal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(bool_comparison))]
|
|
||||||
fn set_async(&self) {
|
fn set_async(&self) {
|
||||||
// Do not signal when we are about to close
|
// Do not signal when we are about to close
|
||||||
if self.deleting.load(AtomicOrdering::Relaxed) {
|
if self.deleting.load(AtomicOrdering::Relaxed) {
|
||||||
|
@ -137,9 +137,14 @@ pub fn verify_block_family(header: &Header, parent: &Header, engine: &EthEngine,
|
|||||||
|
|
||||||
fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &EthEngine) -> Result<(), Error> {
|
fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &EthEngine) -> Result<(), Error> {
|
||||||
let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?;
|
let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?;
|
||||||
|
let max_uncles = engine.maximum_uncle_count(header.number());
|
||||||
if num_uncles != 0 {
|
if num_uncles != 0 {
|
||||||
if num_uncles > engine.maximum_uncle_count() {
|
if num_uncles > max_uncles {
|
||||||
return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles })));
|
return Err(From::from(BlockError::TooManyUncles(OutOfBounds {
|
||||||
|
min: None,
|
||||||
|
max: Some(max_uncles),
|
||||||
|
found: num_uncles,
|
||||||
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut excluded = HashSet::new();
|
let mut excluded = HashSet::new();
|
||||||
@ -268,7 +273,7 @@ pub fn verify_header_params(header: &Header, engine: &EthEngine, is_full: bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is_full {
|
if is_full {
|
||||||
let max_time = get_time().sec as u64 + 30;
|
let max_time = get_time().sec as u64 + 15;
|
||||||
if header.timestamp() > max_time {
|
if header.timestamp() > max_time {
|
||||||
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
|
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
|
||||||
}
|
}
|
||||||
@ -493,7 +498,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(feature="dev", allow(similar_names))]
|
|
||||||
fn test_verify_block() {
|
fn test_verify_block() {
|
||||||
use rlp::RlpStream;
|
use rlp::RlpStream;
|
||||||
|
|
||||||
@ -641,9 +645,15 @@ mod tests {
|
|||||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||||
|
|
||||||
header = good.clone();
|
header = good.clone();
|
||||||
header.set_timestamp(get_time().sec as u64 + 40);
|
header.set_timestamp(get_time().sec as u64 + 20);
|
||||||
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
check_fail_timestamp(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||||
|
|
||||||
|
header = good.clone();
|
||||||
|
header.set_timestamp(get_time().sec as u64 + 10);
|
||||||
|
header.set_uncles_hash(good_uncles_hash.clone());
|
||||||
|
header.set_transactions_root(good_transactions_root.clone());
|
||||||
|
check_ok(basic_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine));
|
||||||
|
|
||||||
header = good.clone();
|
header = good.clone();
|
||||||
header.set_number(9);
|
header.set_number(9);
|
||||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &good_uncles), engine, &bc),
|
||||||
@ -653,7 +663,7 @@ mod tests {
|
|||||||
let mut bad_uncles = good_uncles.clone();
|
let mut bad_uncles = good_uncles.clone();
|
||||||
bad_uncles.push(good_uncle1.clone());
|
bad_uncles.push(good_uncle1.clone());
|
||||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &bad_uncles), engine, &bc),
|
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &bad_uncles), engine, &bc),
|
||||||
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count()), min: None, found: bad_uncles.len() }));
|
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count(header.number())), min: None, found: bad_uncles.len() }));
|
||||||
|
|
||||||
header = good.clone();
|
header = good.clone();
|
||||||
bad_uncles = vec![ good_uncle1.clone(), good_uncle1.clone() ];
|
bad_uncles = vec![ good_uncle1.clone(), good_uncle1.clone() ];
|
||||||
|
@ -96,7 +96,6 @@ pub trait Ext {
|
|||||||
/// Returns Err, if we run out of gas.
|
/// Returns Err, if we run out of gas.
|
||||||
/// Otherwise returns call_result which contains gas left
|
/// Otherwise returns call_result which contains gas left
|
||||||
/// and true if subcall was successfull.
|
/// and true if subcall was successfull.
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
|
||||||
fn call(&mut self,
|
fn call(&mut self,
|
||||||
gas: &U256,
|
gas: &U256,
|
||||||
sender_address: &Address,
|
sender_address: &Address,
|
||||||
|
@ -69,17 +69,17 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
|||||||
),
|
),
|
||||||
Static(
|
Static(
|
||||||
"_ccall",
|
"_ccall",
|
||||||
&[I32; 6],
|
&[I64, I32, I32, I32, I32, I32, I32],
|
||||||
Some(I32),
|
Some(I32),
|
||||||
),
|
),
|
||||||
Static(
|
Static(
|
||||||
"_dcall",
|
"_dcall",
|
||||||
&[I32; 5],
|
&[I64, I32, I32, I32, I32, I32],
|
||||||
Some(I32),
|
Some(I32),
|
||||||
),
|
),
|
||||||
Static(
|
Static(
|
||||||
"_scall",
|
"_scall",
|
||||||
&[I32; 5],
|
&[I64, I32, I32, I32, I32, I32],
|
||||||
Some(I32),
|
Some(I32),
|
||||||
),
|
),
|
||||||
Static(
|
Static(
|
||||||
|
@ -111,6 +111,7 @@ impl vm::Vm for WasmInterpreter {
|
|||||||
address: params.address,
|
address: params.address,
|
||||||
sender: params.sender,
|
sender: params.sender,
|
||||||
origin: params.origin,
|
origin: params.origin,
|
||||||
|
code_address: params.code_address,
|
||||||
value: params.value.value(),
|
value: params.value.value(),
|
||||||
},
|
},
|
||||||
&self.program,
|
&self.program,
|
||||||
|
@ -104,6 +104,7 @@ pub struct RuntimeContext {
|
|||||||
pub address: Address,
|
pub address: Address,
|
||||||
pub sender: Address,
|
pub sender: Address,
|
||||||
pub origin: Address,
|
pub origin: Address,
|
||||||
|
pub code_address: Address,
|
||||||
pub value: U256,
|
pub value: U256,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,6 +306,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
|||||||
//
|
//
|
||||||
// method signature:
|
// method signature:
|
||||||
// fn (
|
// fn (
|
||||||
|
// gas: i64,
|
||||||
// address: *const u8,
|
// address: *const u8,
|
||||||
// val_ptr: *const u8,
|
// val_ptr: *const u8,
|
||||||
// input_ptr: *const u8,
|
// input_ptr: *const u8,
|
||||||
@ -323,6 +325,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
|||||||
//
|
//
|
||||||
// signature (same as static call):
|
// signature (same as static call):
|
||||||
// fn (
|
// fn (
|
||||||
|
// gas: i64,
|
||||||
// address: *const u8,
|
// address: *const u8,
|
||||||
// input_ptr: *const u8,
|
// input_ptr: *const u8,
|
||||||
// input_len: u32,
|
// input_len: u32,
|
||||||
@ -330,7 +333,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
|||||||
// result_len: u32,
|
// result_len: u32,
|
||||||
// ) -> i32
|
// ) -> i32
|
||||||
|
|
||||||
self.do_call(false, CallType::CallCode, context)
|
self.do_call(false, CallType::DelegateCall, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_call(
|
fn do_call(
|
||||||
@ -363,6 +366,9 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
|||||||
let address = self.pop_address(&mut context)?;
|
let address = self.pop_address(&mut context)?;
|
||||||
trace!(target: "wasm", " address: {:?}", address);
|
trace!(target: "wasm", " address: {:?}", address);
|
||||||
|
|
||||||
|
let gas = context.value_stack.pop_as::<i64>()? as u64;
|
||||||
|
trace!(target: "wasm", " gas: {:?}", gas);
|
||||||
|
|
||||||
if let Some(ref val) = val {
|
if let Some(ref val) = val {
|
||||||
let address_balance = self.ext.balance(&self.context.address)
|
let address_balance = self.ext.balance(&self.context.address)
|
||||||
.map_err(|_| UserTrap::BalanceQueryError)?;
|
.map_err(|_| UserTrap::BalanceQueryError)?;
|
||||||
@ -377,16 +383,16 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
|||||||
|
|
||||||
let mut result = Vec::with_capacity(result_alloc_len as usize);
|
let mut result = Vec::with_capacity(result_alloc_len as usize);
|
||||||
result.resize(result_alloc_len as usize, 0);
|
result.resize(result_alloc_len as usize, 0);
|
||||||
let gas = self.gas_left()
|
|
||||||
.map_err(|_| UserTrap::InvalidGasState)?
|
|
||||||
.into();
|
|
||||||
// todo: optimize to use memory views once it's in
|
// todo: optimize to use memory views once it's in
|
||||||
let payload = self.memory.get(input_ptr, input_len as usize)?;
|
let payload = self.memory.get(input_ptr, input_len as usize)?;
|
||||||
|
|
||||||
|
self.charge(|_| gas.into())?;
|
||||||
|
|
||||||
let call_result = self.ext.call(
|
let call_result = self.ext.call(
|
||||||
&gas,
|
&gas.into(),
|
||||||
&self.context.sender,
|
match call_type { CallType::DelegateCall => &self.context.sender, _ => &self.context.address },
|
||||||
&self.context.address,
|
match call_type { CallType::Call | CallType::StaticCall => &address, _ => &self.context.address },
|
||||||
val,
|
val,
|
||||||
&payload,
|
&payload,
|
||||||
&address,
|
&address,
|
||||||
@ -396,12 +402,16 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
|||||||
|
|
||||||
match call_result {
|
match call_result {
|
||||||
vm::MessageCallResult::Success(gas_left, _) => {
|
vm::MessageCallResult::Success(gas_left, _) => {
|
||||||
self.gas_counter = self.gas_limit - gas_left.low_u64();
|
// cannot overflow, before making call gas_counter was incremented with gas, and gas_left < gas
|
||||||
|
self.gas_counter = self.gas_counter - gas_left.low_u64();
|
||||||
|
|
||||||
self.memory.set(result_ptr, &result)?;
|
self.memory.set(result_ptr, &result)?;
|
||||||
Ok(Some(0i32.into()))
|
Ok(Some(0i32.into()))
|
||||||
},
|
},
|
||||||
vm::MessageCallResult::Reverted(gas_left, _) => {
|
vm::MessageCallResult::Reverted(gas_left, _) => {
|
||||||
self.gas_counter = self.gas_limit - gas_left.low_u64();
|
// cannot overflow, before making call gas_counter was incremented with gas, and gas_left < gas
|
||||||
|
self.gas_counter = self.gas_counter - gas_left.low_u64();
|
||||||
|
|
||||||
self.memory.set(result_ptr, &result)?;
|
self.memory.set(result_ptr, &result)?;
|
||||||
Ok(Some((-1i32).into()))
|
Ok(Some((-1i32).into()))
|
||||||
},
|
},
|
||||||
@ -416,6 +426,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
|||||||
{
|
{
|
||||||
// signature (same as code call):
|
// signature (same as code call):
|
||||||
// fn (
|
// fn (
|
||||||
|
// gas: i64,
|
||||||
// address: *const u8,
|
// address: *const u8,
|
||||||
// input_ptr: *const u8,
|
// input_ptr: *const u8,
|
||||||
// input_len: u32,
|
// input_len: u32,
|
||||||
|
@ -60,7 +60,7 @@ fn empty() {
|
|||||||
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
test_finalize(interpreter.exec(params, &mut ext)).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(gas_left, U256::from(99_982));
|
assert_eq!(gas_left, U256::from(96_678));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test checks if the contract deserializes payload header properly.
|
// This test checks if the contract deserializes payload header properly.
|
||||||
@ -112,7 +112,7 @@ fn logger() {
|
|||||||
U256::from(1_000_000_000),
|
U256::from(1_000_000_000),
|
||||||
"Logger sets 0x04 key to the trasferred value"
|
"Logger sets 0x04 key to the trasferred value"
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(19_147));
|
assert_eq!(gas_left, U256::from(15_860));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test checks if the contract can allocate memory and pass pointer to the result stream properly.
|
// This test checks if the contract can allocate memory and pass pointer to the result stream properly.
|
||||||
@ -147,7 +147,7 @@ fn identity() {
|
|||||||
sender,
|
sender,
|
||||||
"Idenity test contract does not return the sender passed"
|
"Idenity test contract does not return the sender passed"
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(99_844));
|
assert_eq!(gas_left, U256::from(96_540));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispersion test sends byte array and expect the contract to 'disperse' the original elements with
|
// Dispersion test sends byte array and expect the contract to 'disperse' the original elements with
|
||||||
@ -180,7 +180,7 @@ fn dispersion() {
|
|||||||
result,
|
result,
|
||||||
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
|
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(96_393));
|
assert_eq!(gas_left, U256::from(96_116));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -208,7 +208,7 @@ fn suicide_not() {
|
|||||||
result,
|
result,
|
||||||
vec![0u8]
|
vec![0u8]
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(96_725));
|
assert_eq!(gas_left, U256::from(96_461));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -240,7 +240,7 @@ fn suicide() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert!(ext.suicides.contains(&refund));
|
assert!(ext.suicides.contains(&refund));
|
||||||
assert_eq!(gas_left, U256::from(96_687));
|
assert_eq!(gas_left, U256::from(96_429));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -270,7 +270,7 @@ fn create() {
|
|||||||
assert!(ext.calls.contains(
|
assert!(ext.calls.contains(
|
||||||
&FakeCall {
|
&FakeCall {
|
||||||
call_type: FakeCallType::Create,
|
call_type: FakeCallType::Create,
|
||||||
gas: U256::from(65_899),
|
gas: U256::from(62_545),
|
||||||
sender_address: None,
|
sender_address: None,
|
||||||
receive_address: None,
|
receive_address: None,
|
||||||
value: Some(1_000_000_000.into()),
|
value: Some(1_000_000_000.into()),
|
||||||
@ -278,9 +278,52 @@ fn create() {
|
|||||||
code_address: None,
|
code_address: None,
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
assert_eq!(gas_left, U256::from(65_892));
|
assert_eq!(gas_left, U256::from(62_538));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn call_msg() {
|
||||||
|
::ethcore_logger::init_log();
|
||||||
|
|
||||||
|
let sender: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
|
||||||
|
let receiver: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
|
||||||
|
let contract_address: Address = "0d461d4174b4ae35775c4a342f1e5e1e4e6c4db5".parse().unwrap();
|
||||||
|
|
||||||
|
let mut params = ActionParams::default();
|
||||||
|
params.sender = sender.clone();
|
||||||
|
params.address = receiver.clone();
|
||||||
|
params.code_address = contract_address.clone();
|
||||||
|
params.gas = U256::from(100_000);
|
||||||
|
params.code = Some(Arc::new(load_sample!("call.wasm")));
|
||||||
|
params.data = Some(Vec::new());
|
||||||
|
|
||||||
|
let mut ext = FakeExt::new();
|
||||||
|
ext.balances.insert(receiver.clone(), U256::from(10000000000u64));
|
||||||
|
|
||||||
|
let gas_left = {
|
||||||
|
let mut interpreter = wasm_interpreter();
|
||||||
|
let result = interpreter.exec(params, &mut ext).expect("Interpreter to execute without any errors");
|
||||||
|
match result {
|
||||||
|
GasLeft::Known(gas_left) => gas_left,
|
||||||
|
GasLeft::NeedsReturn { .. } => { panic!("Call test should not return payload"); },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!(target: "wasm", "fake_calls: {:?}", &ext.calls);
|
||||||
|
assert!(ext.calls.contains(
|
||||||
|
&FakeCall {
|
||||||
|
call_type: FakeCallType::Call,
|
||||||
|
gas: U256::from(33_000),
|
||||||
|
sender_address: Some(receiver),
|
||||||
|
receive_address: Some(Address::from([99, 88, 77, 66, 55, 44, 33, 22, 11, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0])),
|
||||||
|
value: Some(1000000000.into()),
|
||||||
|
data: vec![129u8, 123, 113, 107, 101, 97],
|
||||||
|
code_address: Some(Address::from([99, 88, 77, 66, 55, 44, 33, 22, 11, 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0])),
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(gas_left, U256::from(95_699));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call_code() {
|
fn call_code() {
|
||||||
@ -312,7 +355,7 @@ fn call_code() {
|
|||||||
assert!(ext.calls.contains(
|
assert!(ext.calls.contains(
|
||||||
&FakeCall {
|
&FakeCall {
|
||||||
call_type: FakeCallType::Call,
|
call_type: FakeCallType::Call,
|
||||||
gas: U256::from(98_713),
|
gas: U256::from(20_000),
|
||||||
sender_address: Some(sender),
|
sender_address: Some(sender),
|
||||||
receive_address: Some(receiver),
|
receive_address: Some(receiver),
|
||||||
value: None,
|
value: None,
|
||||||
@ -324,7 +367,7 @@ fn call_code() {
|
|||||||
// siphash result
|
// siphash result
|
||||||
let res = LittleEndian::read_u32(&result[..]);
|
let res = LittleEndian::read_u32(&result[..]);
|
||||||
assert_eq!(res, 4198595614);
|
assert_eq!(res, 4198595614);
|
||||||
assert_eq!(gas_left, U256::from(93_855));
|
assert_eq!(gas_left, U256::from(90_550));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -333,6 +376,7 @@ fn call_static() {
|
|||||||
|
|
||||||
let sender: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
|
let sender: Address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6".parse().unwrap();
|
||||||
let receiver: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
|
let receiver: Address = "01030507090b0d0f11131517191b1d1f21232527".parse().unwrap();
|
||||||
|
let contract_address: Address = "0d461d4174b4ae35775c4a342f1e5e1e4e6c4db5".parse().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
@ -341,6 +385,7 @@ fn call_static() {
|
|||||||
params.code = Some(Arc::new(load_sample!("call_static.wasm")));
|
params.code = Some(Arc::new(load_sample!("call_static.wasm")));
|
||||||
params.data = Some(Vec::new());
|
params.data = Some(Vec::new());
|
||||||
params.value = ActionValue::transfer(1_000_000_000);
|
params.value = ActionValue::transfer(1_000_000_000);
|
||||||
|
params.code_address = contract_address.clone();
|
||||||
|
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
@ -357,9 +402,9 @@ fn call_static() {
|
|||||||
assert!(ext.calls.contains(
|
assert!(ext.calls.contains(
|
||||||
&FakeCall {
|
&FakeCall {
|
||||||
call_type: FakeCallType::Call,
|
call_type: FakeCallType::Call,
|
||||||
gas: U256::from(98_713),
|
gas: U256::from(20_000),
|
||||||
sender_address: Some(sender),
|
sender_address: Some(receiver),
|
||||||
receive_address: Some(receiver),
|
receive_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()),
|
||||||
value: None,
|
value: None,
|
||||||
data: vec![1u8, 2, 3, 5, 7, 11],
|
data: vec![1u8, 2, 3, 5, 7, 11],
|
||||||
code_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()),
|
code_address: Some("13077bfb00000000000000000000000000000000".parse().unwrap()),
|
||||||
@ -370,7 +415,7 @@ fn call_static() {
|
|||||||
let res = LittleEndian::read_u32(&result[..]);
|
let res = LittleEndian::read_u32(&result[..]);
|
||||||
assert_eq!(res, 317632590);
|
assert_eq!(res, 317632590);
|
||||||
|
|
||||||
assert_eq!(gas_left, U256::from(93_855));
|
assert_eq!(gas_left, U256::from(90_550));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Realloc test
|
// Realloc test
|
||||||
@ -393,7 +438,7 @@ fn realloc() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
assert_eq!(result, vec![0u8; 2]);
|
assert_eq!(result, vec![0u8; 2]);
|
||||||
assert_eq!(gas_left, U256::from(96_723));
|
assert_eq!(gas_left, U256::from(96_445));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that contract's ability to read from a storage
|
// Tests that contract's ability to read from a storage
|
||||||
@ -419,7 +464,7 @@ fn storage_read() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(Address::from(&result[12..32]), address);
|
assert_eq!(Address::from(&result[12..32]), address);
|
||||||
assert_eq!(gas_left, U256::from(99_767));
|
assert_eq!(gas_left, U256::from(96_463));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests keccak calculation
|
// Tests keccak calculation
|
||||||
@ -445,7 +490,7 @@ fn keccak() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||||
assert_eq!(gas_left, U256::from(81_446));
|
assert_eq!(gas_left, U256::from(81_067));
|
||||||
}
|
}
|
||||||
|
|
||||||
// memcpy test.
|
// memcpy test.
|
||||||
@ -477,7 +522,7 @@ fn memcpy() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(result, test_payload);
|
assert_eq!(result, test_payload);
|
||||||
assert_eq!(gas_left, U256::from(72_216));
|
assert_eq!(gas_left, U256::from(71_940));
|
||||||
}
|
}
|
||||||
|
|
||||||
// memmove test.
|
// memmove test.
|
||||||
@ -509,7 +554,7 @@ fn memmove() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(result, test_payload);
|
assert_eq!(result, test_payload);
|
||||||
assert_eq!(gas_left, U256::from(72_216));
|
assert_eq!(gas_left, U256::from(71_940));
|
||||||
}
|
}
|
||||||
|
|
||||||
// memset test
|
// memset test
|
||||||
@ -534,7 +579,7 @@ fn memset() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(result, vec![228u8; 8192]);
|
assert_eq!(result, vec![228u8; 8192]);
|
||||||
assert_eq!(gas_left, U256::from(72_196));
|
assert_eq!(gas_left, U256::from(71_921));
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! reqrep_test {
|
macro_rules! reqrep_test {
|
||||||
@ -591,7 +636,7 @@ fn math_add() {
|
|||||||
U256::from_dec_str("1888888888888888888888888888887").unwrap(),
|
U256::from_dec_str("1888888888888888888888888888887").unwrap(),
|
||||||
(&result[..]).into()
|
(&result[..]).into()
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(95_524));
|
assert_eq!(gas_left, U256::from(95_384));
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiplication
|
// multiplication
|
||||||
@ -613,7 +658,7 @@ fn math_mul() {
|
|||||||
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
|
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
|
||||||
(&result[..]).into()
|
(&result[..]).into()
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(94_674));
|
assert_eq!(gas_left, U256::from(94_374));
|
||||||
}
|
}
|
||||||
|
|
||||||
// subtraction
|
// subtraction
|
||||||
@ -635,7 +680,7 @@ fn math_sub() {
|
|||||||
U256::from_dec_str("111111111111111111111111111111").unwrap(),
|
U256::from_dec_str("111111111111111111111111111111").unwrap(),
|
||||||
(&result[..]).into()
|
(&result[..]).into()
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(95_516));
|
assert_eq!(gas_left, U256::from(95_372));
|
||||||
}
|
}
|
||||||
|
|
||||||
// subtraction with overflow
|
// subtraction with overflow
|
||||||
@ -677,7 +722,7 @@ fn math_div() {
|
|||||||
U256::from_dec_str("1125000").unwrap(),
|
U256::from_dec_str("1125000").unwrap(),
|
||||||
(&result[..]).into()
|
(&result[..]).into()
|
||||||
);
|
);
|
||||||
assert_eq!(gas_left, U256::from(88_514));
|
assert_eq!(gas_left, U256::from(88_356));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test checks the ability of wasm contract to invoke
|
// This test checks the ability of wasm contract to invoke
|
||||||
@ -765,7 +810,7 @@ fn externs() {
|
|||||||
"Gas limit requested and returned does not match"
|
"Gas limit requested and returned does not match"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(gas_left, U256::from(94_858));
|
assert_eq!(gas_left, U256::from(95_321));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -791,7 +836,7 @@ fn embedded_keccak() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||||
assert_eq!(gas_left, U256::from(81_446));
|
assert_eq!(gas_left, U256::from(81_067));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test checks the correctness of log extern
|
/// This test checks the correctness of log extern
|
||||||
@ -826,5 +871,5 @@ fn events() {
|
|||||||
assert_eq!(&log_entry.data, b"gnihtemos");
|
assert_eq!(&log_entry.data, b"gnihtemos");
|
||||||
|
|
||||||
assert_eq!(&result, b"gnihtemos");
|
assert_eq!(&result, b"gnihtemos");
|
||||||
assert_eq!(gas_left, U256::from(79_637));
|
assert_eq!(gas_left, U256::from(79_206));
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,6 @@ pub mod aes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ECDH functions
|
/// ECDH functions
|
||||||
#[cfg_attr(feature="dev", allow(similar_names))]
|
|
||||||
pub mod ecdh {
|
pub mod ecdh {
|
||||||
use secp256k1::{ecdh, key, Error as SecpError};
|
use secp256k1::{ecdh, key, Error as SecpError};
|
||||||
use ethkey::{Secret, Public, SECP256K1};
|
use ethkey::{Secret, Public, SECP256K1};
|
||||||
@ -199,7 +198,6 @@ pub mod ecdh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ECIES function
|
/// ECIES function
|
||||||
#[cfg_attr(feature="dev", allow(similar_names))]
|
|
||||||
pub mod ecies {
|
pub mod ecies {
|
||||||
use rcrypto::digest::Digest;
|
use rcrypto::digest::Digest;
|
||||||
use rcrypto::sha2::Sha256;
|
use rcrypto::sha2::Sha256;
|
||||||
|
@ -29,8 +29,6 @@ use presale::PresaleWallet;
|
|||||||
use json::{self, Uuid, OpaqueKeyFile};
|
use json::{self, Uuid, OpaqueKeyFile};
|
||||||
use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret};
|
use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation, OpaqueSecret};
|
||||||
|
|
||||||
const REFRESH_TIME_SEC: u64 = 5;
|
|
||||||
|
|
||||||
/// Accounts store.
|
/// Accounts store.
|
||||||
pub struct EthStore {
|
pub struct EthStore {
|
||||||
store: EthMultiStore,
|
store: EthMultiStore,
|
||||||
@ -49,6 +47,16 @@ impl EthStore {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Modify account refresh timeout - how often they are re-read from `KeyDirectory`.
|
||||||
|
///
|
||||||
|
/// Setting this to low values (or 0) will cause new accounts to be picked up quickly,
|
||||||
|
/// although it may induce heavy disk reads and is not recommended if you manage many keys (say over 10k).
|
||||||
|
///
|
||||||
|
/// By default refreshing is disabled, so only accounts created using this instance of `EthStore` are taken into account.
|
||||||
|
pub fn set_refresh_time(&self, time: Duration) {
|
||||||
|
self.store.set_refresh_time(time)
|
||||||
|
}
|
||||||
|
|
||||||
fn get(&self, account: &StoreAccountRef) -> Result<SafeAccount, Error> {
|
fn get(&self, account: &StoreAccountRef) -> Result<SafeAccount, Error> {
|
||||||
let mut accounts = self.store.get_accounts(account)?.into_iter();
|
let mut accounts = self.store.get_accounts(account)?.into_iter();
|
||||||
accounts.next().ok_or(Error::InvalidAccount)
|
accounts.next().ok_or(Error::InvalidAccount)
|
||||||
@ -254,6 +262,7 @@ pub struct EthMultiStore {
|
|||||||
struct Timestamp {
|
struct Timestamp {
|
||||||
dir_hash: Option<u64>,
|
dir_hash: Option<u64>,
|
||||||
last_checked: Instant,
|
last_checked: Instant,
|
||||||
|
refresh_time: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EthMultiStore {
|
impl EthMultiStore {
|
||||||
@ -272,16 +281,28 @@ impl EthMultiStore {
|
|||||||
timestamp: Mutex::new(Timestamp {
|
timestamp: Mutex::new(Timestamp {
|
||||||
dir_hash: None,
|
dir_hash: None,
|
||||||
last_checked: Instant::now(),
|
last_checked: Instant::now(),
|
||||||
|
// by default we never refresh accounts
|
||||||
|
refresh_time: Duration::from_secs(u64::max_value()),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
store.reload_accounts()?;
|
store.reload_accounts()?;
|
||||||
Ok(store)
|
Ok(store)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Modify account refresh timeout - how often they are re-read from `KeyDirectory`.
|
||||||
|
///
|
||||||
|
/// Setting this to low values (or 0) will cause new accounts to be picked up quickly,
|
||||||
|
/// although it may induce heavy disk reads and is not recommended if you manage many keys (say over 10k).
|
||||||
|
///
|
||||||
|
/// By default refreshing is disabled, so only accounts created using this instance of `EthStore` are taken into account.
|
||||||
|
pub fn set_refresh_time(&self, time: Duration) {
|
||||||
|
self.timestamp.lock().refresh_time = time;
|
||||||
|
}
|
||||||
|
|
||||||
fn reload_if_changed(&self) -> Result<(), Error> {
|
fn reload_if_changed(&self) -> Result<(), Error> {
|
||||||
let mut last_timestamp = self.timestamp.lock();
|
let mut last_timestamp = self.timestamp.lock();
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
if (now - last_timestamp.last_checked) > Duration::from_secs(REFRESH_TIME_SEC) {
|
if now - last_timestamp.last_checked > last_timestamp.refresh_time {
|
||||||
let dir_hash = Some(self.dir.unique_repr()?);
|
let dir_hash = Some(self.dir.unique_repr()?);
|
||||||
last_timestamp.last_checked = now;
|
last_timestamp.last_checked = now;
|
||||||
if last_timestamp.dir_hash == dir_hash {
|
if last_timestamp.dir_hash == dir_hash {
|
||||||
@ -319,22 +340,23 @@ impl EthMultiStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_accounts(&self, account: &StoreAccountRef) -> Result<Vec<SafeAccount>, Error> {
|
fn get_accounts(&self, account: &StoreAccountRef) -> Result<Vec<SafeAccount>, Error> {
|
||||||
{
|
let from_cache = |account| {
|
||||||
let cache = self.cache.read();
|
let cache = self.cache.read();
|
||||||
if let Some(accounts) = cache.get(account) {
|
if let Some(accounts) = cache.get(account) {
|
||||||
if !accounts.is_empty() {
|
if !accounts.is_empty() {
|
||||||
return Ok(accounts.clone())
|
return Some(accounts.clone())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
match from_cache(account) {
|
||||||
|
Some(accounts) => Ok(accounts),
|
||||||
|
None => {
|
||||||
self.reload_if_changed()?;
|
self.reload_if_changed()?;
|
||||||
let cache = self.cache.read();
|
from_cache(account).ok_or(Error::InvalidAccount)
|
||||||
let accounts = cache.get(account).ok_or(Error::InvalidAccount)?;
|
}
|
||||||
if accounts.is_empty() {
|
|
||||||
Err(Error::InvalidAccount)
|
|
||||||
} else {
|
|
||||||
Ok(accounts.clone())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,11 +492,20 @@ impl SimpleSecretStore for EthMultiStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error> {
|
fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error> {
|
||||||
|
let read_from_cache = |address: &Address| {
|
||||||
use std::collections::Bound;
|
use std::collections::Bound;
|
||||||
self.reload_if_changed()?;
|
|
||||||
let cache = self.cache.read();
|
let cache = self.cache.read();
|
||||||
let mut r = cache.range((Bound::Included(*address), Bound::Included(*address)));
|
let mut r = cache.range((Bound::Included(*address), Bound::Included(*address)));
|
||||||
r.next().ok_or(Error::InvalidAccount).map(|(k, _)| k.clone())
|
r.next().map(|(k, _)| k.clone())
|
||||||
|
};
|
||||||
|
|
||||||
|
match read_from_cache(address) {
|
||||||
|
Some(account) => Ok(account),
|
||||||
|
None => {
|
||||||
|
self.reload_if_changed()?;
|
||||||
|
read_from_cache(address).ok_or(Error::InvalidAccount)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error> {
|
fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error> {
|
||||||
|
@ -150,6 +150,9 @@ impl<F: Fetch + 'static> HashFetch for Client<F> {
|
|||||||
URLHintResult::Dapp(dapp) => {
|
URLHintResult::Dapp(dapp) => {
|
||||||
dapp.url()
|
dapp.url()
|
||||||
},
|
},
|
||||||
|
URLHintResult::GithubDapp(content) => {
|
||||||
|
content.url
|
||||||
|
},
|
||||||
URLHintResult::Content(content) => {
|
URLHintResult::Content(content) => {
|
||||||
content.url
|
content.url
|
||||||
},
|
},
|
||||||
|
@ -32,6 +32,10 @@ use bytes::Bytes;
|
|||||||
pub type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
pub type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
||||||
|
|
||||||
const COMMIT_LEN: usize = 20;
|
const COMMIT_LEN: usize = 20;
|
||||||
|
/// GithubHint entries with commit set as `0x0..01` should be treated
|
||||||
|
/// as Github Dapp, downloadable zip files, than can be extracted, containing
|
||||||
|
/// the manifest.json file along with the dapp
|
||||||
|
static GITHUB_DAPP_COMMIT: &[u8; COMMIT_LEN] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
||||||
|
|
||||||
/// RAW Contract interface.
|
/// RAW Contract interface.
|
||||||
/// Should execute transaction using current blockchain state.
|
/// Should execute transaction using current blockchain state.
|
||||||
@ -93,6 +97,8 @@ pub struct Content {
|
|||||||
pub enum URLHintResult {
|
pub enum URLHintResult {
|
||||||
/// Dapp
|
/// Dapp
|
||||||
Dapp(GithubApp),
|
Dapp(GithubApp),
|
||||||
|
/// GithubDapp
|
||||||
|
GithubDapp(Content),
|
||||||
/// Content
|
/// Content
|
||||||
Content(Content),
|
Content(Content),
|
||||||
}
|
}
|
||||||
@ -122,6 +128,15 @@ impl URLHintContract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_urlhint_content(account_slash_repo: String, owner: Address) -> Content {
|
||||||
|
let mime = guess_mime_type(&account_slash_repo).unwrap_or(mime::APPLICATION_JSON);
|
||||||
|
Content {
|
||||||
|
url: account_slash_repo,
|
||||||
|
mime,
|
||||||
|
owner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn decode_urlhint_output(output: (String, ::bigint::hash::H160, Address)) -> Option<URLHintResult> {
|
fn decode_urlhint_output(output: (String, ::bigint::hash::H160, Address)) -> Option<URLHintResult> {
|
||||||
let (account_slash_repo, commit, owner) = output;
|
let (account_slash_repo, commit, owner) = output;
|
||||||
|
|
||||||
@ -130,13 +145,15 @@ fn decode_urlhint_output(output: (String, ::bigint::hash::H160, Address)) -> Opt
|
|||||||
}
|
}
|
||||||
|
|
||||||
let commit = GithubApp::commit(&commit);
|
let commit = GithubApp::commit(&commit);
|
||||||
|
|
||||||
if commit == Some(Default::default()) {
|
if commit == Some(Default::default()) {
|
||||||
let mime = guess_mime_type(&account_slash_repo).unwrap_or(mime::APPLICATION_JSON);
|
let content = get_urlhint_content(account_slash_repo, owner);
|
||||||
return Some(URLHintResult::Content(Content {
|
return Some(URLHintResult::Content(content));
|
||||||
url: account_slash_repo,
|
}
|
||||||
mime: mime,
|
|
||||||
owner: owner,
|
if commit == Some(*GITHUB_DAPP_COMMIT) {
|
||||||
}));
|
let content = get_urlhint_content(account_slash_repo, owner);
|
||||||
|
return Some(URLHintResult::GithubDapp(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (account, repo) = {
|
let (account, repo) = {
|
||||||
|
57
js-old/package-lock.json
generated
57
js-old/package-lock.json
generated
@ -15,9 +15,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@parity/api": {
|
"@parity/api": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.14",
|
||||||
"resolved": "https://registry.npmjs.org/@parity/api/-/api-2.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@parity/api/-/api-2.1.14.tgz",
|
||||||
"integrity": "sha512-HkvMIhIwDMEIyTmXqEjWn1C2qes0qJO270bQldRfCZf0XiOGXG726EzV3FUpUbVONCVQ9riDviAl3fw6D+N6nA==",
|
"integrity": "sha512-1IiaXJCXkhNUNeWiMcLKrdXcPnLjdH58zIc8zk4IgwFvJ3ZNriV1W6lGHghHB9GbNcHgpZdpYt4NUvu67oWZ9w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@parity/abi": "2.1.2",
|
"@parity/abi": "2.1.2",
|
||||||
"@parity/jsonrpc": "2.1.4",
|
"@parity/jsonrpc": "2.1.4",
|
||||||
@ -2165,7 +2165,6 @@
|
|||||||
"version": "6.23.0",
|
"version": "6.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz",
|
||||||
"integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=",
|
"integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"core-js": "2.4.1",
|
"core-js": "2.4.1",
|
||||||
"regenerator-runtime": "0.10.5"
|
"regenerator-runtime": "0.10.5"
|
||||||
@ -2174,8 +2173,7 @@
|
|||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.10.5",
|
"version": "0.10.5",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
|
||||||
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
|
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg="
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3282,8 +3280,7 @@
|
|||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz",
|
||||||
"integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=",
|
"integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -3419,11 +3416,6 @@
|
|||||||
"randomfill": "1.0.3"
|
"randomfill": "1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"crypto-js": {
|
|
||||||
"version": "3.1.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz",
|
|
||||||
"integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU="
|
|
||||||
},
|
|
||||||
"css-color-names": {
|
"css-color-names": {
|
||||||
"version": "0.0.4",
|
"version": "0.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
|
||||||
@ -11017,24 +11009,8 @@
|
|||||||
"react-inspector": {
|
"react-inspector": {
|
||||||
"version": "github:paritytech/react-inspector#73b5214261a5131821eb9088f58d7e5f31210c23",
|
"version": "github:paritytech/react-inspector#73b5214261a5131821eb9088f58d7e5f31210c23",
|
||||||
"requires": {
|
"requires": {
|
||||||
"babel-runtime": "6.26.0",
|
"babel-runtime": "6.23.0",
|
||||||
"is-dom": "1.0.9"
|
"is-dom": "1.0.9"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"babel-runtime": {
|
|
||||||
"version": "6.26.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
|
||||||
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
|
||||||
"requires": {
|
|
||||||
"core-js": "2.5.1",
|
|
||||||
"regenerator-runtime": "0.11.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"core-js": {
|
|
||||||
"version": "2.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
|
|
||||||
"integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs="
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-intl": {
|
"react-intl": {
|
||||||
@ -13494,22 +13470,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web3": {
|
|
||||||
"version": "0.17.0-beta",
|
|
||||||
"resolved": "https://registry.npmjs.org/web3/-/web3-0.17.0-beta.tgz",
|
|
||||||
"integrity": "sha1-V684JFv/ejIJn3zleA+tW7wA2ls=",
|
|
||||||
"requires": {
|
|
||||||
"bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2",
|
|
||||||
"crypto-js": "3.1.8",
|
|
||||||
"utf8": "2.1.2",
|
|
||||||
"xmlhttprequest": "1.8.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"bignumber.js": {
|
|
||||||
"version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"webidl-conversions": {
|
"webidl-conversions": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||||
@ -13813,11 +13773,6 @@
|
|||||||
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=",
|
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"xmlhttprequest": {
|
|
||||||
"version": "1.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
|
|
||||||
"integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
|
|
||||||
},
|
|
||||||
"xss-filters": {
|
"xss-filters": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/xss-filters/-/xss-filters-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/xss-filters/-/xss-filters-1.2.7.tgz",
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"build:app": "webpack --config webpack/app",
|
"build:app": "webpack --config webpack/app",
|
||||||
"build:dll": "webpack --config webpack/vendor",
|
"build:dll": "webpack --config webpack/vendor",
|
||||||
"ci:build": "cross-env NODE_ENV=production npm run build",
|
"ci:build": "cross-env NODE_ENV=production npm run build",
|
||||||
"clean": "rimraf ./.build ./.coverage ./.happypack ./.npmjs ./build ./node_modules/.cache",
|
"clean": "rimraf ./.build ./.coverage ./.happypack ./.npmjs ./node_modules/.cache",
|
||||||
"lint": "npm run lint:css && npm run lint:js",
|
"lint": "npm run lint:css && npm run lint:js",
|
||||||
"lint:css": "stylelint ./src/**/*.css",
|
"lint:css": "stylelint ./src/**/*.css",
|
||||||
"lint:js": "eslint --ignore-path .gitignore ./src/",
|
"lint:js": "eslint --ignore-path .gitignore ./src/",
|
||||||
@ -133,7 +133,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@parity/abi": "2.1.x",
|
"@parity/abi": "2.1.x",
|
||||||
"@parity/api": "2.1.x",
|
"@parity/api": "^2.1.14",
|
||||||
"@parity/wordlist": "1.1.x",
|
"@parity/wordlist": "1.1.x",
|
||||||
"base32.js": "0.1.0",
|
"base32.js": "0.1.0",
|
||||||
"bignumber.js": "3.0.1",
|
"bignumber.js": "3.0.1",
|
||||||
@ -203,7 +203,6 @@
|
|||||||
"utf8": "2.1.2",
|
"utf8": "2.1.2",
|
||||||
"valid-url": "1.0.9",
|
"valid-url": "1.0.9",
|
||||||
"validator": "6.2.0",
|
"validator": "6.2.0",
|
||||||
"web3": "0.17.0-beta",
|
|
||||||
"whatwg-fetch": "2.0.1",
|
"whatwg-fetch": "2.0.1",
|
||||||
"worker-loader": "^0.8.0",
|
"worker-loader": "^0.8.0",
|
||||||
"zxcvbn": "4.4.1"
|
"zxcvbn": "4.4.1"
|
||||||
|
@ -1 +1 @@
|
|||||||
// test script 21
|
// test script 22
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
<div id="container">
|
<div id="container">
|
||||||
<div class="loading">Loading</div>
|
<div class="loading">Loading</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="/parity-utils/inject.js"></script>
|
|
||||||
<script src="vendor.js"></script>
|
<script src="vendor.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
background-color: rgba(0, 0, 0, 0.8);
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: transform ease-out 0.1s;
|
transition: transform ease-out 0.1s;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
|
@ -19,7 +19,7 @@ import { connect } from 'react-redux';
|
|||||||
|
|
||||||
import { hashToImageUrl } from '~/redux/providers/imagesReducer';
|
import { hashToImageUrl } from '~/redux/providers/imagesReducer';
|
||||||
|
|
||||||
import defaultIcon from '../../../assets/images/certifications/unknown.svg';
|
import defaultIcon from '~/../assets/images/certifications/unknown.svg';
|
||||||
|
|
||||||
import styles from './certifications.css';
|
import styles from './certifications.css';
|
||||||
|
|
||||||
@ -28,7 +28,6 @@ class Certifications extends Component {
|
|||||||
address: PropTypes.string.isRequired,
|
address: PropTypes.string.isRequired,
|
||||||
certifications: PropTypes.array.isRequired,
|
certifications: PropTypes.array.isRequired,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
dappsUrl: PropTypes.string.isRequired,
|
|
||||||
showOnlyIcon: PropTypes.bool
|
showOnlyIcon: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ class Certifications extends Component {
|
|||||||
|
|
||||||
renderCertification = (certification) => {
|
renderCertification = (certification) => {
|
||||||
const { name, icon } = certification;
|
const { name, icon } = certification;
|
||||||
const { dappsUrl, showOnlyIcon } = this.props;
|
const { showOnlyIcon } = this.props;
|
||||||
|
|
||||||
const classNames = [
|
const classNames = [
|
||||||
showOnlyIcon
|
showOnlyIcon
|
||||||
@ -68,7 +67,7 @@ class Certifications extends Component {
|
|||||||
className={ styles.icon }
|
className={ styles.icon }
|
||||||
src={
|
src={
|
||||||
icon
|
icon
|
||||||
? `${dappsUrl}${hashToImageUrl(icon)}`
|
? hashToImageUrl(icon)
|
||||||
: defaultIcon
|
: defaultIcon
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -22,7 +22,8 @@ $transitionAll: all 0.75s cubic-bezier(0.23, 1, 0.32, 1);
|
|||||||
.container {
|
.container {
|
||||||
background: $background;
|
background: $background;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
/* Broke after Chrome upgrade, just commenting for now */
|
||||||
|
/* height: 100%; */
|
||||||
padding: 0em;
|
padding: 0em;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -64,7 +65,8 @@ $transitionAll: all 0.75s cubic-bezier(0.23, 1, 0.32, 1);
|
|||||||
.padded {
|
.padded {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
height: 100%;
|
/* Broke after Chrome upgrade, just commenting for now */
|
||||||
|
/* height: 100%; */
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
@ -105,9 +105,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.inputContainer {
|
.inputContainer {
|
||||||
display: flex;
|
justify-content: flex-start;
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
@ -134,8 +132,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.category {
|
.category {
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin: 0 0.5em;
|
margin: 0 0.5em;
|
||||||
max-width: 35em;
|
max-width: 35em;
|
||||||
|
|
||||||
@ -149,12 +145,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cards {
|
.cards {
|
||||||
flex: 1;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ class AddressSelect extends Component {
|
|||||||
|
|
||||||
content = (
|
content = (
|
||||||
<div className={ styles.cards }>
|
<div className={ styles.cards }>
|
||||||
<div>{ cards }</div>
|
{ cards }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,10 @@ class IdentityIcon extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateIcon (_address, images) {
|
updateIcon (_address, images) {
|
||||||
const { api } = this.context;
|
|
||||||
const { button, inline, tiny } = this.props;
|
const { button, inline, tiny } = this.props;
|
||||||
|
|
||||||
if (images[_address]) {
|
if (images[_address]) {
|
||||||
this.setState({ iconsrc: `${api.dappsUrl}${images[_address]}` });
|
this.setState({ iconsrc: images[_address] });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ describe('ui/IdentityIcon', () => {
|
|||||||
const img = render({ address: ADDRESS2 }).find('img');
|
const img = render({ address: ADDRESS2 }).find('img');
|
||||||
|
|
||||||
expect(img).to.have.length(1);
|
expect(img).to.have.length(1);
|
||||||
expect(img.props().src).to.equal('dappsUrl/reduxImage');
|
// expect(img.props().src).to.equal('dappsUrl/reduxImage');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders an <ContractIcon> with no address specified', () => {
|
it('renders an <ContractIcon> with no address specified', () => {
|
||||||
|
@ -82,10 +82,9 @@ $popoverZ: 3600;
|
|||||||
/* but may well be) will scretch to non-visible areas.
|
/* but may well be) will scretch to non-visible areas.
|
||||||
*/
|
*/
|
||||||
&.small {
|
&.small {
|
||||||
margin: 1.5em auto;
|
left: 50%;
|
||||||
max-width: 768px;
|
margin: 1.5em -384px;
|
||||||
position: relative;
|
width: 768px;
|
||||||
width: 75%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@ -29,7 +28,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -47,7 +47,6 @@
|
|||||||
width: calc(.9em + 5px);
|
width: calc(.9em + 5px);
|
||||||
text-transform: initial;
|
text-transform: initial;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
margin-top: -1em;
|
|
||||||
|
|
||||||
> .bar {
|
> .bar {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
|
import { fetchTokens } from '~/redux/providers/tokensActions';
|
||||||
import unknownImage from '~/../assets/images/contracts/unknown-64x64.png';
|
import unknownImage from '~/../assets/images/contracts/unknown-64x64.png';
|
||||||
|
|
||||||
class TokenImage extends Component {
|
class TokenImage extends Component {
|
||||||
@ -29,27 +31,39 @@ class TokenImage extends Component {
|
|||||||
token: PropTypes.shape({
|
token: PropTypes.shape({
|
||||||
image: PropTypes.string,
|
image: PropTypes.string,
|
||||||
address: PropTypes.string
|
address: PropTypes.string
|
||||||
}).isRequired
|
}).isRequired,
|
||||||
|
fetchTokens: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
error: false
|
error: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
componentWillMount () {
|
||||||
|
const { token } = this.props;
|
||||||
|
|
||||||
|
if (token.native) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!token.fetched) {
|
||||||
|
if (!Number.isFinite(token.index)) {
|
||||||
|
return console.warn('no token index', token);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.fetchTokens([ token.index ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { error } = this.state;
|
const { error } = this.state;
|
||||||
const { api } = this.context;
|
|
||||||
const { image, token } = this.props;
|
const { image, token } = this.props;
|
||||||
|
|
||||||
const imageurl = token.image || image;
|
const imageurl = token.image || image;
|
||||||
let imagesrc = unknownImage;
|
let imagesrc = unknownImage;
|
||||||
|
|
||||||
if (imageurl && !error) {
|
if (imageurl && !error) {
|
||||||
const host = /^(\/)?api/.test(imageurl)
|
imagesrc = imageurl;
|
||||||
? api.dappsUrl
|
|
||||||
: '';
|
|
||||||
|
|
||||||
imagesrc = `${host}${imageurl}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -76,7 +90,13 @@ function mapStateToProps (iniState) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps (dispatch) {
|
||||||
|
return bindActionCreators({
|
||||||
|
fetchTokens
|
||||||
|
}, dispatch);
|
||||||
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
null
|
mapDispatchToProps
|
||||||
)(TokenImage);
|
)(TokenImage);
|
||||||
|
@ -51,7 +51,7 @@ const defaultViews = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
contracts: {
|
contracts: {
|
||||||
active: false,
|
active: true,
|
||||||
onlyPersonal: true,
|
onlyPersonal: true,
|
||||||
icon: <ContactsIcon />,
|
icon: <ContactsIcon />,
|
||||||
route: '/contracts',
|
route: '/contracts',
|
||||||
|
1804
js/package-lock.json
generated
1804
js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Parity",
|
"name": "Parity",
|
||||||
"version": "1.9.22",
|
"version": "1.9.40",
|
||||||
"main": "src/index.parity.js",
|
"main": "src/index.parity.js",
|
||||||
"jsnext:main": "src/index.parity.js",
|
"jsnext:main": "src/index.parity.js",
|
||||||
"author": "Parity Team <admin@parity.io>",
|
"author": "Parity Team <admin@parity.io>",
|
||||||
@ -27,7 +27,7 @@
|
|||||||
"build:embed": "cross-env EMBED=1 node webpack/embed",
|
"build:embed": "cross-env EMBED=1 node webpack/embed",
|
||||||
"build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js",
|
"build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js",
|
||||||
"ci:build": "cross-env NODE_ENV=production npm run build",
|
"ci:build": "cross-env NODE_ENV=production npm run build",
|
||||||
"clean": "rimraf ./.build ./.coverage ./.happypack ./build",
|
"clean": "rimraf ./.build ./.coverage ./.happypack",
|
||||||
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
"coveralls": "npm run testCoverage && coveralls < coverage/lcov.info",
|
||||||
"lint": "npm run lint:css && npm run lint:js",
|
"lint": "npm run lint:css && npm run lint:js",
|
||||||
"lint:cached": "npm run lint:css && npm run lint:js:cached",
|
"lint:cached": "npm run lint:css && npm run lint:js:cached",
|
||||||
@ -55,8 +55,6 @@
|
|||||||
"@parity/dapp-signaturereg": "paritytech/dapp-signaturereg",
|
"@parity/dapp-signaturereg": "paritytech/dapp-signaturereg",
|
||||||
"@parity/dapp-tokendeploy": "paritytech/dapp-tokendeploy",
|
"@parity/dapp-tokendeploy": "paritytech/dapp-tokendeploy",
|
||||||
"@parity/dapp-tokenreg": "paritytech/dapp-tokenreg",
|
"@parity/dapp-tokenreg": "paritytech/dapp-tokenreg",
|
||||||
"@parity/dapp-vaults": "paritytech/dapp-vaults",
|
|
||||||
"@parity/dapp-web": "paritytech/dapp-web",
|
|
||||||
"babel-cli": "6.26.0",
|
"babel-cli": "6.26.0",
|
||||||
"babel-core": "6.26.0",
|
"babel-core": "6.26.0",
|
||||||
"babel-eslint": "7.1.1",
|
"babel-eslint": "7.1.1",
|
||||||
@ -70,7 +68,7 @@
|
|||||||
"babel-plugin-transform-runtime": "6.23.0",
|
"babel-plugin-transform-runtime": "6.23.0",
|
||||||
"babel-plugin-webpack-alias": "2.1.2",
|
"babel-plugin-webpack-alias": "2.1.2",
|
||||||
"babel-polyfill": "6.26.0",
|
"babel-polyfill": "6.26.0",
|
||||||
"babel-preset-env": "1.6.0",
|
"babel-preset-env": "1.6.1",
|
||||||
"babel-preset-react": "6.24.1",
|
"babel-preset-react": "6.24.1",
|
||||||
"babel-preset-stage-0": "6.24.1",
|
"babel-preset-stage-0": "6.24.1",
|
||||||
"babel-register": "6.26.0",
|
"babel-register": "6.26.0",
|
||||||
@ -142,14 +140,13 @@
|
|||||||
"yargs": "6.6.0"
|
"yargs": "6.6.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@parity/api": "2.1.x",
|
"@parity/api": "^2.1.14",
|
||||||
"@parity/dapp-accounts": "paritytech/dapp-accounts",
|
|
||||||
"@parity/plugin-signer-account": "paritytech/plugin-signer-account",
|
"@parity/plugin-signer-account": "paritytech/plugin-signer-account",
|
||||||
"@parity/plugin-signer-default": "paritytech/plugin-signer-default",
|
"@parity/plugin-signer-default": "paritytech/plugin-signer-default",
|
||||||
"@parity/plugin-signer-hardware": "paritytech/plugin-signer-hardware",
|
"@parity/plugin-signer-hardware": "paritytech/plugin-signer-hardware",
|
||||||
"@parity/plugin-signer-qr": "paritytech/plugin-signer-qr",
|
"@parity/plugin-signer-qr": "paritytech/plugin-signer-qr",
|
||||||
"@parity/shared": "2.2.x",
|
"@parity/shared": "2.2.14",
|
||||||
"@parity/ui": "~3.0.4",
|
"@parity/ui": "3.0.20",
|
||||||
"keythereum": "1.0.2",
|
"keythereum": "1.0.2",
|
||||||
"lodash.flatten": "4.4.0",
|
"lodash.flatten": "4.4.0",
|
||||||
"lodash.omitby": "4.6.0",
|
"lodash.omitby": "4.6.0",
|
||||||
@ -173,6 +170,6 @@
|
|||||||
"semantic-ui-react": "0.77.0",
|
"semantic-ui-react": "0.77.0",
|
||||||
"solc": "ngotchac/solc-js",
|
"solc": "ngotchac/solc-js",
|
||||||
"store": "1.3.20",
|
"store": "1.3.20",
|
||||||
"web3": "0.17.0-beta"
|
"web3": "1.0.0-beta.26"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
// test script 26
|
// test script 27
|
||||||
|
@ -19,39 +19,35 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 100vh;
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
top: 0;
|
position: absolute;
|
||||||
right: 0;
|
left: 50%;
|
||||||
left: 0;
|
top: 50%;
|
||||||
bottom: 0;
|
transform: translate(-50%, -50%);
|
||||||
opacity: 0.2;
|
|
||||||
position: fixed;
|
|
||||||
padding: 7em;
|
|
||||||
text-align: center;
|
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
opacity: 0.2;
|
||||||
img {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
.content {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-direction: column;
|
position: relative;
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
/* Show scrollbar for Homepage only, dapps' scrollbar are handled inside
|
||||||
padding: 0;
|
* their iframe.
|
||||||
}
|
*/
|
||||||
|
& > div {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
background: red;
|
background: red;
|
||||||
color: white;
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ import Status from '../Status';
|
|||||||
import UpgradeParity from '../UpgradeParity';
|
import UpgradeParity from '../UpgradeParity';
|
||||||
|
|
||||||
import { appLogoDark as parityLogo } from '../config';
|
import { appLogoDark as parityLogo } from '../config';
|
||||||
import Store from './store';
|
|
||||||
import styles from './application.css';
|
import styles from './application.css';
|
||||||
|
|
||||||
const inFrame = window.parent !== window && window.parent.frames.length !== 0;
|
const inFrame = window.parent !== window && window.parent.frames.length !== 0;
|
||||||
@ -54,7 +53,6 @@ class Application extends Component {
|
|||||||
pending: PropTypes.array
|
pending: PropTypes.array
|
||||||
}
|
}
|
||||||
|
|
||||||
store = new Store(this.context.api);
|
|
||||||
hwstore = HardwareStore.get(this.context.api);
|
hwstore = HardwareStore.get(this.context.api);
|
||||||
upgradeStore = UpgradeStore.get(this.context.api);
|
upgradeStore = UpgradeStore.get(this.context.api);
|
||||||
|
|
||||||
@ -77,6 +75,7 @@ class Application extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.application }>
|
<div className={ styles.application }>
|
||||||
|
<img src={ parityLogo } className={ styles.logo } />
|
||||||
{
|
{
|
||||||
blockNumber
|
blockNumber
|
||||||
? <Status upgradeStore={ this.upgradeStore } />
|
? <Status upgradeStore={ this.upgradeStore } />
|
||||||
@ -109,35 +108,29 @@ class Application extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderApp () {
|
renderApp () {
|
||||||
const { children } = this.props;
|
return [
|
||||||
|
<Extension key='extension' />,
|
||||||
return (
|
<FirstRun key='firstrun' />,
|
||||||
<div className={ styles.container }>
|
<Snackbar key='snackbar' />,
|
||||||
<Extension />
|
<UpgradeParity key='upgrade' upgradeStore={ this.upgradeStore } />,
|
||||||
<FirstRun
|
<Errors key='errors' />,
|
||||||
onClose={ this.store.closeFirstrun }
|
this.renderContent()
|
||||||
visible={ this.store.firstrunVisible }
|
];
|
||||||
/>
|
|
||||||
<Snackbar />
|
|
||||||
<UpgradeParity upgradeStore={ this.upgradeStore } />
|
|
||||||
<Errors />
|
|
||||||
<div className={ styles.content }>
|
|
||||||
{ children }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMinimized () {
|
renderMinimized () {
|
||||||
|
return [
|
||||||
|
<Errors key='errors' />,
|
||||||
|
this.renderContent()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
renderContent () {
|
||||||
const { children } = this.props;
|
const { children } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.container }>
|
<div key='content' className={ styles.content }>
|
||||||
<div className={ styles.logo }>
|
{children}
|
||||||
<img src={ parityLogo } />
|
|
||||||
</div>
|
|
||||||
<Errors />
|
|
||||||
{ children }
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
|
||||||
import store from 'store';
|
|
||||||
|
|
||||||
const OLD_LS_FIRST_RUN_KEY = 'showFirstRun';
|
|
||||||
const LS_FIRST_RUN_KEY = '_parity::showFirstRun';
|
|
||||||
|
|
||||||
export default class Store {
|
|
||||||
@observable firstrunVisible = false;
|
|
||||||
|
|
||||||
constructor (api) {
|
|
||||||
// Migrate the old key to the new one
|
|
||||||
this._migrateStore();
|
|
||||||
|
|
||||||
this._api = api;
|
|
||||||
|
|
||||||
// Show the first run the storage doesn't hold `false` value
|
|
||||||
const firstrunVisible = store.get(LS_FIRST_RUN_KEY) !== false;
|
|
||||||
|
|
||||||
// Only check accounts if we might show the first run
|
|
||||||
if (firstrunVisible) {
|
|
||||||
api.transport.once('open', () => {
|
|
||||||
this._checkAccounts();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.firstrunVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@action closeFirstrun = () => {
|
|
||||||
this.toggleFirstrun(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@action toggleFirstrun = (visible = false) => {
|
|
||||||
this.firstrunVisible = visible;
|
|
||||||
|
|
||||||
// There's no need to write to storage that the
|
|
||||||
// First Run should be visible
|
|
||||||
if (!visible) {
|
|
||||||
store.set(LS_FIRST_RUN_KEY, !!visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Migrate the old LocalStorage key format
|
|
||||||
* to the new one
|
|
||||||
*/
|
|
||||||
_migrateStore () {
|
|
||||||
const oldValue = store.get(OLD_LS_FIRST_RUN_KEY);
|
|
||||||
const newValue = store.get(LS_FIRST_RUN_KEY);
|
|
||||||
|
|
||||||
if (newValue === undefined && oldValue !== undefined) {
|
|
||||||
store.set(LS_FIRST_RUN_KEY, oldValue);
|
|
||||||
store.remove(OLD_LS_FIRST_RUN_KEY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_checkAccounts () {
|
|
||||||
return Promise
|
|
||||||
.all([
|
|
||||||
this._api.parity.listVaults(),
|
|
||||||
this._api.parity.allAccountsInfo()
|
|
||||||
])
|
|
||||||
.then(([ vaults, info ]) => {
|
|
||||||
const accounts = Object.keys(info)
|
|
||||||
.filter((address) => info[address].uuid)
|
|
||||||
// In DEV mode, the empty phrase account is already added
|
|
||||||
.filter((address) => address.toLowerCase() !== '0x00a329c0648769a73afac7f9381e08fb43dbea72');
|
|
||||||
|
|
||||||
// Has accounts if any vaults or accounts
|
|
||||||
const hasAccounts = (accounts && accounts.length > 0) || (vaults && vaults.length > 0);
|
|
||||||
|
|
||||||
// Show First Run if no accounts and no vaults
|
|
||||||
this.toggleFirstrun(!hasAccounts);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('checkAccounts', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -53,9 +53,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form {
|
.form {
|
||||||
margin-top: 0.75em;
|
margin-top: 1em;
|
||||||
padding: 0 4em;
|
padding: 0 4em;
|
||||||
text-align: left;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timestamp {
|
.timestamp {
|
||||||
@ -71,14 +71,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icons {
|
.icons {
|
||||||
padding-top: 1.5em;
|
margin-top: 2em;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon,
|
.icon,
|
||||||
.iconSmall {
|
.iconSmall {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 1em;
|
margin-top: 2em;
|
||||||
padding-bottom: 1em;
|
padding: 0 1.5em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,10 +93,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.console {
|
.console {
|
||||||
|
width: 80%;
|
||||||
font-family: 'Roboto Mono', monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
background: rgba(0, 0, 0, 0.25);
|
background: rgba(0, 0, 0, 0.65);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding: 0 0.25em;
|
padding: 0.5em 0.25em;
|
||||||
|
margin: 1em auto;
|
||||||
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
@ -123,10 +127,11 @@
|
|||||||
color: rgb(208, 208, 208);
|
color: rgb(208, 208, 208);
|
||||||
}
|
}
|
||||||
|
|
||||||
.formInput input {
|
.formInput input[type=text] {
|
||||||
background: rgba(0, 0, 0, 0.25) !important;
|
background: rgba(0, 0, 0, 0.25) !important;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.formInput input:focus {
|
.formInput input[type=text]:focus {
|
||||||
background: rgba(0, 0, 0, 0.25) !important;
|
background: rgba(0, 0, 0, 0.25) !important;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
import GradientBg from '@parity/ui/lib/GradientBg';
|
import GradientBg from '@parity/ui/lib/GradientBg';
|
||||||
import Input from '@parity/ui/lib/Form/Input';
|
import Input from '@parity/ui/lib/Form/Input';
|
||||||
import { CompareIcon, ComputerIcon, DashboardIcon, VpnIcon } from '@parity/ui/lib/Icons';
|
import { CompareIcon, ComputerIcon, DashboardIcon, KeyIcon } from '@parity/ui/lib/Icons';
|
||||||
|
|
||||||
import styles from './connection.css';
|
import styles from './connection.css';
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ class Connection extends Component {
|
|||||||
<div className={ styles.icon }>
|
<div className={ styles.icon }>
|
||||||
{
|
{
|
||||||
needsToken
|
needsToken
|
||||||
? <VpnIcon className={ styles.svg } />
|
? <KeyIcon className={ styles.svg } />
|
||||||
: <DashboardIcon className={ styles.svg } />
|
: <DashboardIcon className={ styles.svg } />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -90,18 +90,12 @@ class Connection extends Component {
|
|||||||
<div>
|
<div>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='connection.noConnection'
|
id='connection.noConnection'
|
||||||
defaultMessage='Unable to make a connection to the Parity Secure API. To update your secure token or to generate a new one, run: {newToken} and paste the generated token into the space below.'
|
defaultMessage='To proceed you need to generate a new security token by running the following command in your terminal {newToken} Then copy & paste the newly generated token here'
|
||||||
values={ {
|
values={ {
|
||||||
newToken: <div className={ styles.console }>parity signer new-token</div>
|
newToken: <div className={ styles.console }>$ parity signer new-token</div>
|
||||||
} }
|
} }
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.timestamp }>
|
|
||||||
<FormattedMessage
|
|
||||||
id='connection.timestamp'
|
|
||||||
defaultMessage='Ensure that both the Parity node and this machine connecting have computer clocks in-sync with each other and with a timestamp server, ensuring both successful token validation and block operations.'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={ styles.form }>
|
<div className={ styles.form }>
|
||||||
<Input
|
<Input
|
||||||
className={ styles.formInput }
|
className={ styles.formInput }
|
||||||
@ -120,7 +114,7 @@ class Connection extends Component {
|
|||||||
hint={
|
hint={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='connection.token.hint'
|
id='connection.token.hint'
|
||||||
defaultMessage='Insert the generated token here'
|
defaultMessage='xxXX-Xxxx-xXxx-XxXX'
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onChange={ this.onChangeToken }
|
onChange={ this.onChangeToken }
|
||||||
|
@ -15,22 +15,20 @@
|
|||||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.frame {
|
.frame,
|
||||||
|
.full {
|
||||||
background: white;
|
background: white;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: 0;
|
border: 0;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.full {
|
.full {
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: white;
|
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
|
@ -19,7 +19,6 @@ import { observer } from 'mobx-react';
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import Api from '@parity/api';
|
|
||||||
import builtinDapps from '@parity/shared/lib/config/dappsBuiltin.json';
|
import builtinDapps from '@parity/shared/lib/config/dappsBuiltin.json';
|
||||||
import viewsDapps from '@parity/shared/lib/config/dappsViews.json';
|
import viewsDapps from '@parity/shared/lib/config/dappsViews.json';
|
||||||
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
||||||
@ -27,15 +26,7 @@ import HistoryStore from '@parity/shared/lib/mobx/historyStore';
|
|||||||
|
|
||||||
import styles from './dapp.css';
|
import styles from './dapp.css';
|
||||||
|
|
||||||
const internalDapps = []
|
const internalDapps = [].concat(viewsDapps, builtinDapps);
|
||||||
.concat(viewsDapps, builtinDapps)
|
|
||||||
.map((app) => {
|
|
||||||
if (app.id && app.id.substr(0, 2) !== '0x') {
|
|
||||||
app.id = Api.util.sha3(app.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return app;
|
|
||||||
});
|
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export default class Dapp extends Component {
|
export default class Dapp extends Component {
|
||||||
@ -130,13 +121,9 @@ export default class Dapp extends Component {
|
|||||||
dapphost = '';
|
dapphost = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const appId = this.context.api.util.isHex(app.id)
|
|
||||||
? app.id
|
|
||||||
: this.context.api.sha3(app.url);
|
|
||||||
|
|
||||||
src = window.location.protocol === 'file:'
|
src = window.location.protocol === 'file:'
|
||||||
? `dapps/${appId}/index.html`
|
? `dapps/${app.id}/index.html`
|
||||||
: `${dapphost}/dapps/${appId}/index.html`;
|
: `${dapphost}/dapps/${app.id}/index.html`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,4 +6,16 @@ To be clear with the terminology used in the code here:
|
|||||||
- a *methodGroup* is the grouping of similar methods (see `methodGroups.js`)
|
- a *methodGroup* is the grouping of similar methods (see `methodGroups.js`)
|
||||||
- a *permission* is a boolean which tells if an app is allowed to call a method or not
|
- a *permission* is a boolean which tells if an app is allowed to call a method or not
|
||||||
- a *request* is when an app prompts the shell to call a method
|
- a *request* is when an app prompts the shell to call a method
|
||||||
- a *requestGroup* is an array of *requests* whose methods are in the same *methodGroup*
|
- a *requestGroup* is a map of the following form
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
appId1: {
|
||||||
|
methodGroup1: [request1, request2] // This is a requestGroup sub-item
|
||||||
|
},
|
||||||
|
appId2: {
|
||||||
|
methodGroup1: [request1]
|
||||||
|
methodGroup2: [request3]
|
||||||
|
},
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.requestGroupSubItem {
|
||||||
|
margin-top: 2px;
|
||||||
|
|
||||||
|
.requestGroupSubItemTitle {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import Popup from 'semantic-ui-react/dist/commonjs/modules/Popup';
|
||||||
|
import Button from '@parity/ui/lib/Button';
|
||||||
|
|
||||||
|
import methodGroups from '../../methodGroups';
|
||||||
|
import styles from './RequestGroupSubItem.css';
|
||||||
|
|
||||||
|
export default class RequestGroupSubItem extends PureComponent {
|
||||||
|
handleApprove = () => this.props.onApprove(this.props.requests, this.props.groupId)
|
||||||
|
|
||||||
|
handleReject = () => this.props.onReject(this.props.requests)
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { groupId } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.requestGroupSubItem }>
|
||||||
|
<span className={ styles.requestGroupSubItemTitle }>
|
||||||
|
Permission for{' '}
|
||||||
|
<Popup
|
||||||
|
trigger={ <span>{groupId}</span> }
|
||||||
|
content={ `Requested methods: ${methodGroups[groupId].methods.join(', ')}` }
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
size='mini'
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='dappRequests.request.buttons.approve'
|
||||||
|
defaultMessage='Approve'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onClick={ this.handleApprove }
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
size='mini'
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='dappRequests.request.buttons.reject'
|
||||||
|
defaultMessage='Reject'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onClick={ this.handleReject }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestGroupSubItem.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
groupId: PropTypes.string,
|
||||||
|
onApprove: PropTypes.func.isRequired,
|
||||||
|
onReject: PropTypes.func.isRequired,
|
||||||
|
requests: PropTypes.array.isRequired
|
||||||
|
};
|
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './RequestGroupSubItem';
|
@ -28,12 +28,4 @@ $backgroundTwo: #e57a00;
|
|||||||
> span {
|
> span {
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.requestGroup {
|
|
||||||
margin-top: 2px;
|
|
||||||
|
|
||||||
.requestGroupTitle {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,49 +14,25 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { PureComponent } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import Popup from 'semantic-ui-react/dist/commonjs/modules/Popup';
|
|
||||||
import Button from '@parity/ui/lib/Button';
|
|
||||||
|
|
||||||
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
import DappsStore from '@parity/shared/lib/mobx/dappsStore';
|
||||||
|
|
||||||
|
import RequestGroupSubItem from './RequestGroupSubItem';
|
||||||
import styles from './RequestGroups.css';
|
import styles from './RequestGroups.css';
|
||||||
|
|
||||||
export default class RequestGroups extends PureComponent {
|
export default class RequestGroups extends Component {
|
||||||
state = {
|
handleApproveRequestGroup = (requests, groupId) => {
|
||||||
opened: false
|
this.props.onApproveRequestGroup(requests, groupId, this.props.appId);
|
||||||
};
|
|
||||||
|
|
||||||
handleApproveRequestGroup = groupId => {
|
|
||||||
const { requestGroups, onApproveRequestGroup } = this.props;
|
|
||||||
|
|
||||||
onApproveRequestGroup(Object.values(requestGroups[groupId].map(({ requestId }) => requestId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
handleRejectRequestGroup = groupId => {
|
|
||||||
const { requestGroups, onRejectRequestGroup } = this.props;
|
|
||||||
|
|
||||||
onRejectRequestGroup(Object.values(requestGroups[groupId].map(({ requestId }) => requestId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
renderPopupContent = groupId => {
|
|
||||||
const { requestGroups } = this.props;
|
|
||||||
// Get unique list of methods in that request group
|
|
||||||
const requestedMethods = [...new Set(
|
|
||||||
Object.values(requestGroups[groupId])
|
|
||||||
.map(request => request.data.method || request.data.params[0])
|
|
||||||
)];
|
|
||||||
|
|
||||||
return `Requested methods: ${requestedMethods.join(', ')}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
appId,
|
appId,
|
||||||
requestGroups
|
requestGroups,
|
||||||
|
onRejectRequestGroup
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const app = DappsStore.get().getAppById(appId);
|
const app = DappsStore.get().getAppById(appId);
|
||||||
@ -72,35 +48,13 @@ export default class RequestGroups extends PureComponent {
|
|||||||
} }
|
} }
|
||||||
/>
|
/>
|
||||||
{Object.keys(requestGroups).map(groupId => (
|
{Object.keys(requestGroups).map(groupId => (
|
||||||
<div key={ `${appId}-${groupId}` } className={ styles.requestGroup }>
|
<RequestGroupSubItem
|
||||||
<span className={ styles.requestGroupTitle }>
|
key={ `${appId}-${groupId}` }
|
||||||
Permission for{' '}
|
groupId={ groupId }
|
||||||
<Popup
|
requests={ requestGroups[groupId] }
|
||||||
trigger={ <span>{groupId}</span> }
|
onApprove={ this.handleApproveRequestGroup }
|
||||||
content={ this.renderPopupContent(groupId) }
|
onReject={ onRejectRequestGroup }
|
||||||
/>
|
/>
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
size='mini'
|
|
||||||
label={
|
|
||||||
<FormattedMessage
|
|
||||||
id='dappRequests.request.buttons.approve'
|
|
||||||
defaultMessage='Approve'
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onClick={ () => this.handleApproveRequestGroup(groupId) }
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
size='mini'
|
|
||||||
label={
|
|
||||||
<FormattedMessage
|
|
||||||
id='dappRequests.request.buttons.reject'
|
|
||||||
defaultMessage='Reject'
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onClick={ () => this.handleRejectRequestGroup(groupId) }
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import methodGroups from './methodGroups';
|
||||||
import RequestGroups from './RequestGroups';
|
import RequestGroups from './RequestGroups';
|
||||||
import Store from './store';
|
import Store from './store';
|
||||||
import styles from './dappRequests.css';
|
import styles from './dappRequests.css';
|
||||||
@ -24,12 +25,16 @@ import styles from './dappRequests.css';
|
|||||||
class DappRequests extends Component {
|
class DappRequests extends Component {
|
||||||
store = Store.get();
|
store = Store.get();
|
||||||
|
|
||||||
handleApproveRequestGroup = requestIds => {
|
// When we approve a requestGroup, when approve all the requests, and add permissions
|
||||||
requestIds.forEach(this.store.approveRequest);
|
// to all the other methods in the same methodGroup
|
||||||
|
handleApproveRequestGroup = (requests, groupId, appId) => {
|
||||||
|
requests.map(({ requestId }) => requestId).forEach(this.store.approveRequest);
|
||||||
|
methodGroups[groupId].methods.forEach(method => this.store.addAppPermission(method, appId));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleRejectRequestGroup = requestIds => {
|
// When we reject a requestGroup, we reject the requests in that group
|
||||||
requestIds.forEach(this.store.rejectRequest);
|
handleRejectRequestGroup = requests => {
|
||||||
|
requests.map(({ requestId }) => requestId).forEach(this.store.rejectRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
@ -17,16 +17,33 @@
|
|||||||
const methodGroups = {
|
const methodGroups = {
|
||||||
shell: {
|
shell: {
|
||||||
methods: [
|
methods: [
|
||||||
|
'shell_loadApp'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
dapps: {
|
||||||
|
methods: [
|
||||||
|
'parity_dappsRefresh',
|
||||||
|
'parity_dappsUrl',
|
||||||
'shell_getApps',
|
'shell_getApps',
|
||||||
'shell_getFilteredMethods',
|
'shell_getMethodPermissions'
|
||||||
'shell_getMethodGroups',
|
]
|
||||||
'shell_getMethodPermissions',
|
},
|
||||||
|
dappsEdit: {
|
||||||
|
methods: [
|
||||||
|
'shell_setAppPinned',
|
||||||
'shell_setAppVisibility',
|
'shell_setAppVisibility',
|
||||||
'shell_setMethodPermissions'
|
'shell_setMethodPermissions'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
accountsView: {
|
accounts: {
|
||||||
methods: ['parity_accountsInfo', 'parity_allAccountsInfo']
|
methods: [
|
||||||
|
'parity_accountsInfo',
|
||||||
|
'parity_allAccountsInfo',
|
||||||
|
'parity_getNewDappsAddresses',
|
||||||
|
'parity_getNewDappsDefaultAddress',
|
||||||
|
'parity_hardwareAccountsInfo',
|
||||||
|
'parity_lockedHardwareAccountsInfo'
|
||||||
|
]
|
||||||
},
|
},
|
||||||
accountsCreate: {
|
accountsCreate: {
|
||||||
methods: [
|
methods: [
|
||||||
@ -40,35 +57,67 @@ const methodGroups = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
accountsEdit: {
|
accountsEdit: {
|
||||||
methods: ['parity_setAccountName', 'parity_setAccountMeta']
|
|
||||||
},
|
|
||||||
upgrade: {
|
|
||||||
methods: [
|
methods: [
|
||||||
'parity_consensusCapability',
|
'parity_setAccountName',
|
||||||
'parity_executeUpgrade',
|
'parity_setAccountMeta',
|
||||||
'parity_upgradeReady',
|
'parity_hardwarePinMatrixAck',
|
||||||
'parity_versionInfo'
|
'parity_setNewDappsAddresses',
|
||||||
|
'parity_setNewDappsDefaultAddress'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
accountsDelete: {
|
||||||
|
methods: [
|
||||||
|
'parity_killAccount',
|
||||||
|
'parity_removeAddress'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
vaults: {
|
vaults: {
|
||||||
methods: [
|
methods: [
|
||||||
'parity_changeVault',
|
|
||||||
'parity_changeVaultPassword',
|
|
||||||
'parity_closeVault',
|
'parity_closeVault',
|
||||||
'parity_getVaultMeta',
|
'parity_getVaultMeta',
|
||||||
'parity_listVaults',
|
'parity_listVaults',
|
||||||
'parity_listOpenedVaults',
|
'parity_listOpenedVaults',
|
||||||
'parity_newVault',
|
'parity_openVault'
|
||||||
'parity_openVault',
|
]
|
||||||
|
},
|
||||||
|
vaultsCreate: {
|
||||||
|
methods: [
|
||||||
|
'parity_newVault'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
vaultsEdit: {
|
||||||
|
methods: [
|
||||||
|
'parity_changeVault',
|
||||||
|
'parity_changeVaultPassword',
|
||||||
'parity_setVaultMeta'
|
'parity_setVaultMeta'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
other: {
|
signerRequests: {
|
||||||
methods: [
|
methods: [
|
||||||
'parity_checkRequest',
|
'parity_checkRequest',
|
||||||
'parity_hashContent',
|
|
||||||
'parity_localTransactions'
|
'parity_localTransactions'
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
signerConfirm: {
|
||||||
|
methods: [
|
||||||
|
'parity_confirmRequest',
|
||||||
|
'parity_confirmRequestRaw',
|
||||||
|
'parity_rejectRequest'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
methods: [
|
||||||
|
'parity_hashContent',
|
||||||
|
'parity_consensusCapability',
|
||||||
|
'parity_upgradeReady',
|
||||||
|
'parity_versionInfo',
|
||||||
|
'parity_wsUrl'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
nodeUpgrade: {
|
||||||
|
methods: [
|
||||||
|
'parity_executeUpgrade'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ export default class Store {
|
|||||||
|
|
||||||
accumulator[appId] = accumulator[appId] || {};
|
accumulator[appId] = accumulator[appId] || {};
|
||||||
accumulator[appId][methodGroup] = accumulator[appId][methodGroup] || [];
|
accumulator[appId][methodGroup] = accumulator[appId][methodGroup] || [];
|
||||||
accumulator[appId][methodGroup].push({ data, requestId }); // Append the requestId field in the request object
|
accumulator[appId][methodGroup].push({ data, requestId }); // Push request & append the requestId field in the request object
|
||||||
|
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}, {});
|
}, {});
|
||||||
@ -99,7 +99,7 @@ export default class Store {
|
|||||||
this.requests = { ...this.requests };
|
this.requests = { ...this.requests };
|
||||||
};
|
};
|
||||||
|
|
||||||
getPermissionId = (method, appId) => `${method}:${appId}` // Create an id to identify permissions based on method and appId
|
getPermissionId = (method, appId) => `${method}:${appId}`; // Create an id to identify permissions based on method and appId
|
||||||
|
|
||||||
getMethodFromRequest = requestId => {
|
getMethodFromRequest = requestId => {
|
||||||
const { data: { method, params } } = this.requests[requestId];
|
const { data: { method, params } } = this.requests[requestId];
|
||||||
@ -131,13 +131,10 @@ export default class Store {
|
|||||||
};
|
};
|
||||||
|
|
||||||
setPermissions = _permissions => {
|
setPermissions = _permissions => {
|
||||||
const permissions = {};
|
this.permissions = {
|
||||||
|
...this.permissions,
|
||||||
Object.keys(_permissions).forEach(id => {
|
..._permissions
|
||||||
permissions[id] = !!_permissions[id];
|
};
|
||||||
});
|
|
||||||
|
|
||||||
this.permissions = permissions;
|
|
||||||
this.savePermissions();
|
this.savePermissions();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -245,14 +242,9 @@ export default class Store {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
const _method = api ? params[0] : method;
|
||||||
(method &&
|
|
||||||
methodGroupFromMethod[method] &&
|
if (methodGroupFromMethod[_method] && !this.hasTokenPermission(_method, token)) {
|
||||||
!this.hasTokenPermission(method, token)) ||
|
|
||||||
(api &&
|
|
||||||
methodGroupFromMethod[params[0]] &&
|
|
||||||
!this.hasTokenPermission(method, token))
|
|
||||||
) {
|
|
||||||
this.queueRequest(id, { // The requestId of a request is the id inside data
|
this.queueRequest(id, { // The requestId of a request is the id inside data
|
||||||
data,
|
data,
|
||||||
source
|
source
|
||||||
|
54
js/src/Dapps/DappCard/dappCard.css
Normal file
54
js/src/Dapps/DappCard/dappCard.css
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
margin-top: 3em;
|
||||||
|
|
||||||
|
.pin {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 1.6em;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pin.pinned {
|
||||||
|
display: block;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.pin {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: block;
|
||||||
|
padding-top: 1em;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-top: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
js/src/Dapps/DappCard/dappCard.js
Normal file
72
js/src/Dapps/DappCard/dappCard.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
|
import DappIcon from '@parity/ui/lib/DappIcon';
|
||||||
|
import Header from 'semantic-ui-react/dist/commonjs/elements/Header';
|
||||||
|
import Button from 'semantic-ui-react/dist/commonjs/elements/Button';
|
||||||
|
|
||||||
|
import styles from './dappCard.css';
|
||||||
|
|
||||||
|
export default class DappCard extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
app: PropTypes.object.isRequired,
|
||||||
|
availability: PropTypes.string.isRequired,
|
||||||
|
className: PropTypes.string,
|
||||||
|
onPin: PropTypes.func,
|
||||||
|
pinned: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
handlePin = () => this.props.onPin(this.props.app.id)
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { app, availability, className, pinned } = this.props;
|
||||||
|
|
||||||
|
if (app.onlyPersonal && availability !== 'personal') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ [styles.card, className].join(' ') }>
|
||||||
|
<Button
|
||||||
|
size='mini'
|
||||||
|
icon='pin'
|
||||||
|
circular
|
||||||
|
className={ [styles.pin, pinned && styles.pinned].join(' ') }
|
||||||
|
onClick={ this.handlePin }
|
||||||
|
/>
|
||||||
|
<div className={ styles.content }>
|
||||||
|
<Link to={ app.url === 'web' ? '/web' : `/${app.id}` } >
|
||||||
|
<DappIcon
|
||||||
|
app={ app }
|
||||||
|
className={ styles.image }
|
||||||
|
/>
|
||||||
|
<Header
|
||||||
|
as='h5'
|
||||||
|
textAlign='center'
|
||||||
|
className={ styles.title }
|
||||||
|
>
|
||||||
|
{app.name}
|
||||||
|
</Header>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
js/src/Dapps/DappCard/index.js
Normal file
17
js/src/Dapps/DappCard/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './dappCard';
|
@ -16,13 +16,46 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
|
background: rgba(40, 40, 40, 0.85);
|
||||||
color: white;
|
color: white;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
margin: 0 auto;
|
padding: 4em 2em;
|
||||||
text-align: left;
|
position: fixed;
|
||||||
max-width: 980px;
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
& > div:first-child {
|
div {
|
||||||
padding-bottom: 1em;
|
max-width: 640px;
|
||||||
|
margin: 1em auto;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accept {
|
||||||
|
label {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionTitle {
|
||||||
|
padding: 2em 0 0 4em !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dapps {
|
||||||
|
padding: 0 1.5em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.dapp {
|
||||||
|
width: 12em;
|
||||||
|
margin-left: 2em;
|
||||||
|
margin-right: 2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user