Merge branch 'master' into secretstore_kovan

This commit is contained in:
Svyatoslav Nikolsky 2017-12-27 11:44:28 +03:00
commit c0e7abcc81
203 changed files with 6090 additions and 1869 deletions

84
.github/CODE_OF_CONDUCT.md vendored Normal file
View 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 peoples 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 someones 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 venuesonline and in-personas 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
View 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.

View File

@ -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
View File

@ -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"

View File

@ -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",
]

View File

@ -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.
---- ----

View File

@ -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"]

View File

@ -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 = []

View File

@ -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>;

View File

@ -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)
}, },

View File

@ -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;

View File

@ -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;

View File

@ -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)
} }

View File

@ -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");

View File

@ -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);
}

View File

@ -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.

View File

@ -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 = []

View File

@ -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`

View File

@ -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,

View 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 } } } }
}
}

View File

@ -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 } } } },

View File

@ -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

View File

@ -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.

View File

@ -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,

View File

@ -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();

View File

@ -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();

View File

@ -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();
}
} }

View File

@ -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());
} }
} }

View File

@ -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());
} }
} }

View File

@ -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)
} }

View File

@ -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(())

View File

@ -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!()

View File

@ -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)

View File

@ -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())));
} }
} }

View File

@ -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),

View File

@ -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;

View File

@ -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"))

View File

@ -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>| {

View File

@ -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
//! //!

View File

@ -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,

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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) {

View File

@ -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`

View File

@ -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();

View File

@ -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,

View File

@ -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();

View File

@ -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,

View File

@ -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) {

View File

@ -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() ];

View File

@ -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,

View File

@ -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(

View File

@ -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,

View File

@ -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,

View File

@ -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));
} }

View File

@ -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;

View File

@ -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> {

View File

@ -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
}, },

View File

@ -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) = {

View File

@ -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",

View File

@ -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"

View File

@ -1 +1 @@
// test script 21 // test script 22

View File

@ -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>

View File

@ -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);

View File

@ -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
} }
/> />

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -335,7 +335,7 @@ class AddressSelect extends Component {
content = ( content = (
<div className={ styles.cards }> <div className={ styles.cards }>
<div>{ cards }</div> { cards }
</div> </div>
); );
} }

View File

@ -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;
} }

View File

@ -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', () => {

View File

@ -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%;
} }
} }

View File

@ -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 {

View File

@ -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;

View File

@ -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);

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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"
} }
} }

View File

@ -1 +1 @@
// test script 26 // test script 27

View File

@ -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;
}
} }

View File

@ -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>
); );
} }

View File

@ -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);
});
}
}

View File

@ -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;
} }

View File

@ -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 &amp; 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 }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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]
},
// ...
}
```

View File

@ -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;
}
}

View File

@ -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
};

View 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 './RequestGroupSubItem';

View File

@ -28,12 +28,4 @@ $backgroundTwo: #e57a00;
> span { > span {
margin-right: 30px; margin-right: 30px;
} }
.requestGroup {
margin-top: 2px;
.requestGroupTitle {
margin-right: 10px;
}
}
} }

View File

@ -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>
); );

View File

@ -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 () {

View File

@ -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'
]
} }
}; };

View File

@ -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

View 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;
}
}
}

View 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>
);
}
}

View 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';

View File

@ -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