Compare commits

...

53 Commits

Author SHA1 Message Date
GitLab Build Bot
71a928110c js-precompiled 20161116-110138
Former-commit-id: 1b4aca869111c0dc871f20e5b2e09f37318e76aa
2016-11-16 12:11:19 +01:00
Gav Wood
ea4da34dac Merge pull request #3464 from ethcore/eip170-beta
[beta] EIP-170

Former-commit-id: 2388d265741f379d054df3b0beaf8c639c4648c8
2016-11-16 11:23:43 +08:00
Gav Wood
7a15ea448d Merge pull request #3465 from ethcore/backporting
Backports to beta

Former-commit-id: b44486946a2f1e3188f4181f1022423b0f5ab4e6
2016-11-16 11:21:43 +08:00
Gav Wood
13300b066e Merge pull request #3463 from ethcore/b-rsv
Backport: additional fields on transaction and receipt
Former-commit-id: 1252463146ac92c94f300b14620337bac289a3e3
2016-11-16 11:21:27 +08:00
Jaco Greeff
5a40dba9ab Fix transfer token decimal calculation (#3445)
* Fix decimal calculation

* Recalc when shorcutting estimate


Former-commit-id: e7f457cf1b0fa66964320b259a70ae196fff50a7
2016-11-15 22:00:36 +01:00
Jaco Greeff
a80e19e51e Swap from base to decimals
Former-commit-id: ea84d832a60c4bba00e17d64b9e8882785bf404f
2016-11-15 21:58:22 +01:00
Robert Habermeier
53bbe0d959 test previous code fetch
Former-commit-id: 0c5f895a0f2a7f073d8f3998fe81648305a53665
2016-11-15 21:57:59 +01:00
Gav Wood
094fad1155 whitespace
[ci:skip]

Former-commit-id: 674566eeb7b065056f408e5ceeba7ec887a2c82d
2016-11-15 21:57:53 +01:00
Robert Habermeier
2255b389cc fetch known code from the database during restoration
previously it kept all seen code in memory, leading to
high memory usage by the end of state restoration


Former-commit-id: 749391f3353d186d9be2e60fbc7f2f822408f8e3
2016-11-15 21:57:43 +01:00
Arkadiy Paronyan
e0a86a9a06 Optimize memory footprint (#3376)
Former-commit-id: 562bcac82c6efe2e4e95fe0d2d80a91baff964ef
2016-11-15 21:57:02 +01:00
Tomasz Drwięga
fb443dbe16 Fixing parsing passwords from file (#3367)
* fixing parsing passwords as inputs

* Fixing typo in test


Former-commit-id: b5e1b7fefc49b415e3d217f8e17bde32ee3ad51c
2016-11-15 21:54:59 +01:00
Tomasz Drwięga
603c52f82d Fix spurious signer tests failures (#3312)
* Increasing sleep time for signer tests

* Attempt re-connections instead of delaying tests execution


Former-commit-id: b839f5874ac63299e21f2924157824440ddc0d55
2016-11-15 21:54:11 +01:00
Jaco Greeff
98598d312d Load external, builtin & local apps in parallel (#3340)
Former-commit-id: c19af314f9d6d0f692618bd0fcc50fb85d173e4d
2016-11-15 21:53:59 +01:00
Chuck LeDuc Díaz
c2b7d58aaf Clarify error message to indicate (#3359)
Indicate that Signer *needs* to be re-enabled, not that it *was* re-enabled.

Former-commit-id: 1b3a9bac556e38093c316d665e6138664d7d90a6
2016-11-15 21:53:51 +01:00
Nicolas Gotchac
3bcf8a84ce Check totalBalance > 0 // Better account selection (#3347)
Former-commit-id: cc2aa32c6b4b0a466e47eeb63271db7f13592047
2016-11-15 21:53:21 +01:00
Nicolas Gotchac
e018395c05 Fixed Unregister for Contract Owner only #3321 (#3346)
Former-commit-id: c171207bfafe98d3e25e409fdd8b36bc43985496
2016-11-15 21:53:08 +01:00
arkpar
69d32b884f Set HF block number
Former-commit-id: 5496abf21b140eb75842f6f87a3c56b0f0433876
2016-11-15 21:46:05 +01:00
Arkadiy Paronyan
f3693a0a43 Update test client with max code size
Former-commit-id: 36244abbe86c4620fbfd258a382be819cae4145c
2016-11-15 21:02:35 +01:00
arkpar
f91c3d9d62 fixed test
Former-commit-id: 702d0066c7ed9ef019620e4f00e690c1cd730f91
2016-11-15 21:02:26 +01:00
Gav Wood
b007c7225f Update max code size.
Former-commit-id: 54bae3d00fab74f17767cef6d95ee52271d9486e
2016-11-15 21:01:46 +01:00
Gav Wood
0b2eb3a4c3 Introduce the actual max code size.
Former-commit-id: c87dec7ec4ec4798ce00fb18f798fb762df04954
2016-11-15 21:00:40 +01:00
Gav Wood
780cf0ce1a Restrict max code size to 23999 bytes for EIP-150 and after.
Former-commit-id: 379c1e17d6740be225ed99bad73732330bd9c10a
2016-11-15 21:00:30 +01:00
Tomasz Drwięga
f264d10cc5 Exposing state root and logsBloom in RPC receipts (#3174)
Former-commit-id: 6eeb7a3e5c8354ec9de4027a9d7668b8bf29f4a2
2016-11-15 20:59:08 +01:00
Tomasz Drwięga
f52aee83bc Exposing v,r,s from transaction signature in RPC (#3172)
Former-commit-id: bb138aa03c05b3f19ef0633acc7ecc5212b21663
2016-11-15 20:58:33 +01:00
GitLab Build Bot
afa21ce001 [ci skip] js-precompiled 20161114-201045
Former-commit-id: 08a4220f4657af62d4077d824e9c4ca6fae200de
2016-11-14 20:12:02 +00:00
Denis S. Soldatov aka General-Beck
5ef8c75808 Update gitlab-ci
remove -Zorbit=off
switch to rust 1.13

Former-commit-id: 6c65186e9c06120103dc4ed85f3b6a10c4691edc
2016-11-14 23:47:00 +04:00
GitLab Build Bot
aedd7477ab [ci skip] js-precompiled 20161114-154951
Former-commit-id: 86e77f22a0b5dec3e8d731d15152431da597d8ca
2016-11-14 15:51:04 +00:00
Gav Wood
979e519c79 Merge pull request #3424 from ethcore/backporting
v1.4.3 in beta

Former-commit-id: ca1f043b5ef62aab46b1300635453ada66a5fc2d
2016-11-14 16:32:22 +01:00
arkpar
2799a26d66 v1.4.3
Former-commit-id: acab16f14572e85df1f426d45213147b4ec2b01b
2016-11-14 13:37:34 +01:00
GitLab Build Bot
95d57c839d [ci skip] js-precompiled 20161112-203324
Former-commit-id: 619b709619bf585a9c6281da382a229c0b0c7575
2016-11-12 20:34:44 +00:00
GitLab Build Bot
6a46168fb7 js-precompiled 20161110-160103
Former-commit-id: b14aed734e1f16676b2ec442b1b5a63d86f7bb5d
2016-11-10 17:02:57 +01:00
Jaco Greeff
3da0632771 Make transactions load (#3348)
Former-commit-id: 11a485ea1abb82551f0369b88cfce1ac9a43ce55
2016-11-10 16:39:20 +01:00
arkpar
613b89010f Updated tests
Former-commit-id: 1e3255e6f10dad8b7a0fd0e36ab3aa358144ac40
2016-11-10 16:23:48 +01:00
arkpar
e85ffdbcd1 Updated tests
Former-commit-id: 9f79e6a91837099d7aa537c7c13e64a5e1d2cc77
2016-11-10 16:10:29 +01:00
Arkadiy Paronyan
f5e1bf08ab Disarm the HF and add more bootnodes (#3323)
* Disarm the HF

* More bootnodes

* Updated tests


Former-commit-id: 828de69b1b0011b90812d53ffaa13ed6be2cdd15
2016-11-10 16:10:14 +01:00
GitLab Build Bot
77f3b87627 js-precompiled 20161110-143746
Former-commit-id: fcf0b92f05731b817dd82bde6632bd58b237de7a
2016-11-10 15:44:27 +01:00
Arkadiy Paronyan
75166bd0e0 Backporting to beta (#3344)
* Disarm the HF and add more bootnodes (#3323)

* Disarm the HF

* More bootnodes

* Updated tests

* Windows app and installer fixes (#3338)

* Windows app and installer fixes

* Sorted out comments


Former-commit-id: f64a70feb8594ab4c9494a56702b8283c06a0d19
2016-11-10 15:17:18 +01:00
arkpar
623fc569c2 Fixed MD5 generation
Former-commit-id: 3f885a87bb50a159f82c8b8a1cda0e32b015db27
2016-11-10 14:51:37 +01:00
GitLab Build Bot
7e77f1b62c [ci skip] js-precompiled 20161109-211612
Former-commit-id: f57c299d090347467c4917a1f6a9528936d5314b
2016-11-09 21:17:25 +00:00
Jaco Greeff
e919b2d597 Remove 127.0.0.1 references (#3303)
Former-commit-id: 10ff9e134bad432871f860b9e588624dedb43038
2016-11-09 20:40:57 +01:00
Jaco Greeff
8660b057bf Handle redirects from /api/content on manifest.json gracefully (#3315)
* Add redirect follow mode to manifest.json

* Remove (now) unused count parameter

* autoRewrite: true for dev mode proxy redirects


Former-commit-id: 73143932199b78961760208a9f20dac62b55f0bd
2016-11-09 20:40:57 +01:00
arkpar
e8d6c3a699 v1.4.2
Former-commit-id: 612229ca2ffa1cbb9060c219eac81b4d569df969
2016-11-09 20:40:57 +01:00
Tomasz Drwięga
d0df85d50e Dapps interface RPC (#3311)
* Dapps Interface RPC

* Adding JS apis

* Support for signer interface in proxypac and embeds

* Fixing tests

* fixing tests again


Former-commit-id: 7b998f7ebf1f13bc8e2d948ae896b78e5870b53a
2016-11-09 20:40:57 +01:00
Arkadiy Paronyan
20ca56490e Additional snapshot sync checks (#3318)
* Additional snapshot sync checks

* Proper checks

* Proper highset block check


Former-commit-id: 402a6ca55670f9c197b3d673e91528b853b1b7d6
2016-11-09 20:40:57 +01:00
Jaco Greeff
bfc99f5a76 Fix signer token updates (#3302)
* Manual bump of package.json (recovery)

* Debug

* Simplify status connections


Former-commit-id: c5d0c002b60adeabd7726050437d0632763629ed
2016-11-09 20:40:57 +01:00
Jaco Greeff
59372af0af Update account recovery phrase hint
Former-commit-id: 016e9fd1ab905f46f63bbd0a85210ddcf4cb47cc
2016-11-09 20:40:57 +01:00
Gav Wood
d898cc49ed New transaction tests (#3313)
* Add new transaction tests.

* Add new test.


Former-commit-id: 4549bfc759ee8095965ac34f9173796ce07835a1
2016-11-09 20:40:57 +01:00
Jaco Greeff
adf4e65759 expose api as window.secureApi (#3207)
Former-commit-id: 6b1ca33b8da4ddd96efb28b879e568f713b5fb29
2016-11-09 20:40:57 +01:00
Arkadiy Paronyan
1d2fbdebb2 Fixes for open UI after installation (#3300)
Former-commit-id: 373d61f0102ea6767027b233f756d89b9f838f52
2016-11-09 20:40:57 +01:00
Arkadiy Paronyan
184b0f27e7 Fixed uncle details (#3299)
Former-commit-id: 297b84f4eb80db16a5c33966892b585e43590c11
2016-11-09 20:40:57 +01:00
Jaco Greeff
618cc072b9 Change to more common focused spelling (#3264)
Former-commit-id: b39e5438d9aa2cecab3cc880181d065758a8dd87
2016-11-09 20:40:57 +01:00
Jaco Greeff
f9a75e8e57 Updated blance display with max decimals (#3266)
Former-commit-id: 308371799a47aea45dfceed9b8273f85b5dff728
2016-11-09 20:40:57 +01:00
Björn Wagner
31d75c2ba5 Fix typo (#3298)
Former-commit-id: 5f7bfe2926ff291670b56b7d14ddd9a4e4a4b979
2016-11-09 20:40:57 +01:00
81 changed files with 784 additions and 442 deletions

View File

@@ -21,12 +21,12 @@ linux-stable:
script:
- cargo build --release $CARGOFLAGS
- strip target/release/parity
- md5sum target/release/parity >> parity.md5
- md5sum target/release/parity > parity.md5
- sh scripts/deb-build.sh amd64
- cp target/release/parity deb/usr/bin/parity
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
- dpkg-deb -b deb "parity_"$VER"_amd64.deb"
- md5sum "parity_"$VER"_amd64.deb" >> "parity_"$VER"_amd64.deb.md5"
- md5sum "parity_"$VER"_amd64.deb" > "parity_"$VER"_amd64.deb.md5"
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-linux-gnu/parity --body target/release/parity
@@ -88,7 +88,7 @@ linux-centos:
- export CC="gcc"
- cargo build --release $CARGOFLAGS
- strip target/release/parity
- md5sum target/release/parity >> parity.md5
- md5sum target/release/parity > parity.md5
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-unknown-centos-gnu/parity --body target/release/parity
@@ -113,12 +113,12 @@ linux-i686:
- export HOST_CXX=g++
- cargo build --target i686-unknown-linux-gnu --release $CARGOFLAGS
- strip target/i686-unknown-linux-gnu/release/parity
- md5sum target/i686-unknown-linux-gnu/release/parity >> parity.md5
- md5sum target/i686-unknown-linux-gnu/release/parity > parity.md5
- sh scripts/deb-build.sh i386
- cp target/i686-unknown-linux-gnu/release/parity deb/usr/bin/parity
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
- dpkg-deb -b deb "parity_"$VER"_i386.deb"
- md5sum "parity_"$VER"_i386.deb" >> "parity_"$VER"_i386.deb.md5"
- md5sum "parity_"$VER"_i386.deb" > "parity_"$VER"_i386.deb.md5"
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/i686-unknown-linux-gnu/parity --body target/i686-unknown-linux-gnu/release/parity
@@ -152,12 +152,12 @@ linux-armv7:
- cat .cargo/config
- cargo build --target armv7-unknown-linux-gnueabihf --release $CARGOFLAGS
- arm-linux-gnueabihf-strip target/armv7-unknown-linux-gnueabihf/release/parity
- md5sum target/armv7-unknown-linux-gnueabihf/release/parity >> parity.md5
- md5sum target/armv7-unknown-linux-gnueabihf/release/parity > parity.md5
- sh scripts/deb-build.sh armhf
- cp target/armv7-unknown-linux-gnueabihf/release/parity deb/usr/bin/parity
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
- dpkg-deb -b deb "parity_"$VER"_armhf.deb"
- md5sum "parity_"$VER"_armhf.deb" >> "parity_"$VER"_armhf.deb.md5"
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/armv7-unknown-linux-gnueabihf/parity --body target/armv7-unknown-linux-gnueabihf/release/parity
@@ -191,12 +191,12 @@ linux-arm:
- cat .cargo/config
- cargo build --target arm-unknown-linux-gnueabihf --release $CARGOFLAGS
- arm-linux-gnueabihf-strip target/arm-unknown-linux-gnueabihf/release/parity
- md5sum target/arm-unknown-linux-gnueabihf/release/parity >> parity.md5
- md5sum target/arm-unknown-linux-gnueabihf/release/parity > parity.md5
- sh scripts/deb-build.sh armhf
- cp target/arm-unknown-linux-gnueabihf/release/parity deb/usr/bin/parity
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
- dpkg-deb -b deb "parity_"$VER"_armhf.deb"
- md5sum "parity_"$VER"_armhf.deb" >> "parity_"$VER"_armhf.deb.md5"
- md5sum "parity_"$VER"_armhf.deb" > "parity_"$VER"_armhf.deb.md5"
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabihf/parity --body target/arm-unknown-linux-gnueabihf/release/parity
@@ -230,7 +230,7 @@ linux-armv6:
- cat .cargo/config
- cargo build --target arm-unknown-linux-gnueabi --release $CARGOFLAGS
- arm-linux-gnueabi-strip target/arm-unknown-linux-gnueabi/release/parity
- md5sum target/arm-unknown-linux-gnueabi/release/parity >> parity.md5
- md5sum target/arm-unknown-linux-gnueabi/release/parity > parity.md5
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/arm-unknown-linux-gnueabi/parity --body target/arm-unknown-linux-gnueabi/release/parity
@@ -262,12 +262,12 @@ linux-aarch64:
- cat .cargo/config
- cargo build --target aarch64-unknown-linux-gnu --release $CARGOFLAGS
- aarch64-linux-gnu-strip target/aarch64-unknown-linux-gnu/release/parity
- md5sum target/aarch64-unknown-linux-gnu/release/parity >> parity.md5
- md5sum target/aarch64-unknown-linux-gnu/release/parity > parity.md5
- sh scripts/deb-build.sh arm64
- cp target/aarch64-unknown-linux-gnu/release/parity deb/usr/bin/parity
- export VER=$(grep -m 1 version Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n")
- dpkg-deb -b deb "parity_"$VER"_arm64.deb"
- md5sum "parity_"$VER"_arm64.deb" >> "parity_"$VER"_arm64.deb.md5"
- md5sum "parity_"$VER"_arm64.deb" > "parity_"$VER"_arm64.deb.md5"
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/aarch64-unknown-linux-gnu/parity --body target/aarch64-unknown-linux-gnu/release/parity
@@ -292,16 +292,16 @@ darwin:
- cargo build --release -p ethstore $CARGOFLAGS
- cargo build --release $CARGOFLAGS
- rm -rf parity.md5
- md5sum target/release/parity >> parity.md5
- md5sum target/release/parity > parity.md5
- packagesbuild -v mac/Parity.pkgproj
- mv target/release/Parity\ Ethereum.pkg parity-1.4.0-osx-installer-EXPERIMENTAL.pkg
- md5sum parity-1.4.0-osx-installer-EXPERIMENTAL.pkg >> parity-1.4.0-osx-installer-EXPERIMENTAL.pkg.md5
- mv target/release/Parity\ Ethereum.pkg parity-osx-installer-EXPERIMENTAL.pkg
- md5sum parity-osx-installer-EXPERIMENTAL.pkg > parity-osx-installer-EXPERIMENTAL.pkg.md5
- aws configure set aws_access_key_id $s3_key
- aws configure set aws_secret_access_key $s3_secret
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity --body target/release/parity
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity.md5 --body parity.md5
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity-1.4.0-osx-installer-EXPERIMENTAL.pkg --body parity-1.4.0-osx-installer-EXPERIMENTAL.pkg
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity-1.4.0-osx-installer-EXPERIMENTAL.pkg.md5 --body parity-1.4.0-osx-installer-EXPERIMENTAL.pkg.md5
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity-osx-installer-EXPERIMENTAL.pkg --body parity-osx-installer-EXPERIMENTAL.pkg
- aws s3api put-object --bucket builds-parity --key $CI_BUILD_REF_NAME/x86_64-apple-darwin/parity-osx-installer-EXPERIMENTAL.pkg.md5 --body parity-osx-installer-EXPERIMENTAL.pkg.md5
tags:
- osx
artifacts:
@@ -321,7 +321,7 @@ windows:
- set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt
- set LIB=C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64
- set RUST_BACKTRACE=1
- set RUSTFLAGS=%RUSTFLAGS% -Zorbit=off
- set RUSTFLAGS=%RUSTFLAGS%
- rustup default stable-x86_64-pc-windows-msvc
- cargo build --release %CARGOFLAGS%
- curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll

40
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
[root]
name = "parity"
version = "1.4.1"
version = "1.4.3"
dependencies = [
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -21,7 +21,7 @@ dependencies = [
"ethcore-rpc 1.4.0",
"ethcore-signer 1.4.0",
"ethcore-stratum 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"ethsync 1.4.0",
"fdlimit 0.1.0",
"hyper 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -289,7 +289,7 @@ dependencies = [
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"ethjson 0.1.0",
"ethkey 0.2.0",
"ethstore 0.1.0",
@@ -312,7 +312,7 @@ dependencies = [
[[package]]
name = "ethcore-bigint"
version = "0.1.1"
version = "0.1.2"
dependencies = [
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -336,7 +336,7 @@ dependencies = [
"ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-devtools 1.4.0",
"ethcore-rpc 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"fetch 0.1.0",
"hyper 0.9.4 (git+https://github.com/ethcore/hyper)",
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -381,7 +381,7 @@ name = "ethcore-ipc"
version = "1.4.0"
dependencies = [
"ethcore-devtools 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -428,7 +428,7 @@ dependencies = [
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -439,7 +439,7 @@ name = "ethcore-logger"
version = "1.4.0"
dependencies = [
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -455,7 +455,7 @@ dependencies = [
"bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"ethcrypto 0.1.0",
"ethkey 0.2.0",
"igd 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -482,7 +482,7 @@ dependencies = [
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-ipc 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"ethcrypto 0.1.0",
"ethjson 0.1.0",
"ethkey 0.2.0",
@@ -511,7 +511,7 @@ dependencies = [
"ethcore-devtools 1.4.0",
"ethcore-io 1.4.0",
"ethcore-rpc 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -530,7 +530,7 @@ dependencies = [
"ethcore-ipc 1.4.0",
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"json-tcp-server 0.1.0 (git+https://github.com/ethcore/json-tcp-server)",
"jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -541,7 +541,7 @@ dependencies = [
[[package]]
name = "ethcore-util"
version = "1.4.1"
version = "1.4.3"
dependencies = [
"ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -549,7 +549,7 @@ dependencies = [
"elastic-array 0.6.0 (git+https://github.com/ethcore/elastic-array)",
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
"ethcore-bigint 0.1.1",
"ethcore-bigint 0.1.2",
"ethcore-bloom-journal 0.1.0",
"ethcore-devtools 1.4.0",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -580,7 +580,7 @@ name = "ethcrypto"
version = "0.1.0"
dependencies = [
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
"ethcore-bigint 0.1.1",
"ethcore-bigint 0.1.2",
"ethkey 0.2.0",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -590,7 +590,7 @@ dependencies = [
name = "ethjson"
version = "0.1.0"
dependencies = [
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -603,7 +603,7 @@ version = "0.2.0"
dependencies = [
"docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)",
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
"ethcore-bigint 0.1.1",
"ethcore-bigint 0.1.2",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -643,7 +643,7 @@ dependencies = [
"ethcore-ipc-codegen 1.4.0",
"ethcore-ipc-nano 1.4.0",
"ethcore-network 1.4.0",
"ethcore-util 1.4.1",
"ethcore-util 1.4.3",
"heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1249,7 +1249,7 @@ dependencies = [
[[package]]
name = "parity-ui-precompiled"
version = "1.4.0"
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#9f553876095b366e4675590b575d87c68b3ad256"
source = "git+https://github.com/ethcore/js-precompiled.git?branch=beta#b0eae71ecc5655021b1ea2a06760b20dee286569"
dependencies = [
"parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1463,7 +1463,7 @@ name = "rlp"
version = "0.1.0"
dependencies = [
"elastic-array 0.6.0 (git+https://github.com/ethcore/elastic-array)",
"ethcore-bigint 0.1.1",
"ethcore-bigint 0.1.2",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@@ -1,7 +1,7 @@
[package]
description = "Ethcore client."
name = "parity"
version = "1.4.1"
version = "1.4.3"
license = "GPL-3.0"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"

View File

@@ -47,7 +47,7 @@ pub struct ContentFetcher<R: URLHint = URLHintContract> {
resolver: R,
cache: Arc<Mutex<ContentCache>>,
sync: Arc<SyncStatus>,
embeddable_at: Option<u16>,
embeddable_on: Option<(String, u16)>,
}
impl<R: URLHint> Drop for ContentFetcher<R> {
@@ -59,7 +59,7 @@ impl<R: URLHint> Drop for ContentFetcher<R> {
impl<R: URLHint> ContentFetcher<R> {
pub fn new(resolver: R, sync_status: Arc<SyncStatus>, embeddable_at: Option<u16>) -> Self {
pub fn new(resolver: R, sync_status: Arc<SyncStatus>, embeddable_on: Option<(String, u16)>) -> Self {
let mut dapps_path = env::temp_dir();
dapps_path.push(random_filename());
@@ -68,17 +68,17 @@ impl<R: URLHint> ContentFetcher<R> {
resolver: resolver,
sync: sync_status,
cache: Arc::new(Mutex::new(ContentCache::default())),
embeddable_at: embeddable_at,
embeddable_on: embeddable_on,
}
}
fn still_syncing(port: Option<u16>) -> Box<Handler> {
fn still_syncing(address: Option<(String, u16)>) -> Box<Handler> {
Box::new(ContentHandler::error(
StatusCode::ServiceUnavailable,
"Sync In Progress",
"Your node is still syncing. We cannot resolve any content before it's fully synced.",
Some("<a href=\"javascript:window.location.reload()\">Refresh</a>"),
port,
address,
))
}
@@ -145,7 +145,7 @@ impl<R: URLHint> ContentFetcher<R> {
match content {
// Don't serve dapps if we are still syncing (but serve content)
Some(URLHintResult::Dapp(_)) if self.sync.is_major_importing() => {
(None, Self::still_syncing(self.embeddable_at))
(None, Self::still_syncing(self.embeddable_on.clone()))
},
Some(URLHintResult::Dapp(dapp)) => {
let (handler, fetch_control) = ContentFetcherHandler::new(
@@ -155,9 +155,9 @@ impl<R: URLHint> ContentFetcher<R> {
id: content_id.clone(),
dapps_path: self.dapps_path.clone(),
on_done: Box::new(on_done),
embeddable_at: self.embeddable_at,
embeddable_on: self.embeddable_on.clone(),
},
self.embeddable_at,
self.embeddable_on.clone(),
);
(Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box<Handler>)
@@ -172,13 +172,13 @@ impl<R: URLHint> ContentFetcher<R> {
content_path: self.dapps_path.clone(),
on_done: Box::new(on_done),
},
self.embeddable_at,
self.embeddable_on.clone(),
);
(Some(ContentStatus::Fetching(fetch_control)), Box::new(handler) as Box<Handler>)
},
None if self.sync.is_major_importing() => {
(None, Self::still_syncing(self.embeddable_at))
(None, Self::still_syncing(self.embeddable_on.clone()))
},
None => {
// This may happen when sync status changes in between
@@ -188,7 +188,7 @@ impl<R: URLHint> ContentFetcher<R> {
"Resource Not Found",
"Requested resource was not found.",
None,
self.embeddable_at,
self.embeddable_on.clone(),
)) as Box<Handler>)
},
}
@@ -293,7 +293,7 @@ struct DappInstaller {
id: String,
dapps_path: PathBuf,
on_done: Box<Fn(String, Option<LocalPageEndpoint>) + Send>,
embeddable_at: Option<u16>,
embeddable_on: Option<(String, u16)>,
}
impl DappInstaller {
@@ -386,7 +386,7 @@ impl ContentValidator for DappInstaller {
try!(manifest_file.write_all(manifest_str.as_bytes()));
// Create endpoint
let app = LocalPageEndpoint::new(target, manifest.clone().into(), PageCache::Enabled, self.embeddable_at);
let app = LocalPageEndpoint::new(target, manifest.clone().into(), PageCache::Enabled, self.embeddable_on.clone());
// Return modified app manifest
Ok((manifest.id.clone(), app))

View File

@@ -97,12 +97,12 @@ fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo {
})
}
pub fn local_endpoints(dapps_path: String, signer_port: Option<u16>) -> Endpoints {
pub fn local_endpoints(dapps_path: String, signer_address: Option<(String, u16)>) -> Endpoints {
let mut pages = Endpoints::new();
for dapp in local_dapps(dapps_path) {
pages.insert(
dapp.id,
Box::new(LocalPageEndpoint::new(dapp.path, dapp.info, PageCache::Disabled, signer_port))
Box::new(LocalPageEndpoint::new(dapp.path, dapp.info, PageCache::Disabled, signer_address.clone()))
);
}
pages

View File

@@ -37,26 +37,26 @@ pub fn utils() -> Box<Endpoint> {
Box::new(PageEndpoint::with_prefix(parity_ui::App::default(), UTILS_PATH.to_owned()))
}
pub fn all_endpoints(dapps_path: String, signer_port: Option<u16>) -> Endpoints {
pub fn all_endpoints(dapps_path: String, signer_address: Option<(String, u16)>) -> Endpoints {
// fetch fs dapps at first to avoid overwriting builtins
let mut pages = fs::local_endpoints(dapps_path, signer_port);
let mut pages = fs::local_endpoints(dapps_path, signer_address.clone());
// NOTE [ToDr] Dapps will be currently embeded on 8180
insert::<parity_ui::App>(&mut pages, "ui", Embeddable::Yes(signer_port));
pages.insert("proxy".into(), ProxyPac::boxed(signer_port));
insert::<parity_ui::App>(&mut pages, "ui", Embeddable::Yes(signer_address.clone()));
pages.insert("proxy".into(), ProxyPac::boxed(signer_address));
pages
}
fn insert<T : WebApp + Default + 'static>(pages: &mut Endpoints, id: &str, embed_at: Embeddable) {
pages.insert(id.to_owned(), Box::new(match embed_at {
Embeddable::Yes(port) => PageEndpoint::new_safe_to_embed(T::default(), port),
Embeddable::Yes(address) => PageEndpoint::new_safe_to_embed(T::default(), address),
Embeddable::No => PageEndpoint::new(T::default()),
}));
}
enum Embeddable {
Yes(Option<u16>),
Yes(Option<(String, u16)>),
#[allow(dead_code)]
No,
}

View File

@@ -32,7 +32,7 @@ pub struct ContentHandler {
content: String,
mimetype: Mime,
write_pos: usize,
safe_to_embed_at_port: Option<u16>,
safe_to_embed_on: Option<(String, u16)>,
}
impl ContentHandler {
@@ -44,31 +44,31 @@ impl ContentHandler {
Self::new(StatusCode::NotFound, content, mimetype)
}
pub fn html(code: StatusCode, content: String, embeddable_at: Option<u16>) -> Self {
Self::new_embeddable(code, content, mime!(Text/Html), embeddable_at)
pub fn html(code: StatusCode, content: String, embeddable_on: Option<(String, u16)>) -> Self {
Self::new_embeddable(code, content, mime!(Text/Html), embeddable_on)
}
pub fn error(code: StatusCode, title: &str, message: &str, details: Option<&str>, embeddable_at: Option<u16>) -> Self {
pub fn error(code: StatusCode, title: &str, message: &str, details: Option<&str>, embeddable_on: Option<(String, u16)>) -> Self {
Self::html(code, format!(
include_str!("../error_tpl.html"),
title=title,
message=message,
details=details.unwrap_or_else(|| ""),
version=version(),
), embeddable_at)
), embeddable_on)
}
pub fn new(code: StatusCode, content: String, mimetype: Mime) -> Self {
Self::new_embeddable(code, content, mimetype, None)
}
pub fn new_embeddable(code: StatusCode, content: String, mimetype: Mime, embeddable_at: Option<u16>) -> Self {
pub fn new_embeddable(code: StatusCode, content: String, mimetype: Mime, embeddable_on: Option<(String, u16)>) -> Self {
ContentHandler {
code: code,
content: content,
mimetype: mimetype,
write_pos: 0,
safe_to_embed_at_port: embeddable_at,
safe_to_embed_on: embeddable_on,
}
}
}
@@ -85,7 +85,7 @@ impl server::Handler<HttpStream> for ContentHandler {
fn on_response(&mut self, res: &mut server::Response) -> Next {
res.set_status(self.code);
res.headers_mut().set(header::ContentType(self.mimetype.clone()));
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_at_port.clone());
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_on.clone());
Next::write()
}

View File

@@ -138,7 +138,7 @@ pub struct ContentFetcherHandler<H: ContentValidator> {
client: Option<Client>,
installer: H,
request_url: Option<Url>,
embeddable_at: Option<u16>,
embeddable_on: Option<(String, u16)>,
}
impl<H: ContentValidator> Drop for ContentFetcherHandler<H> {
@@ -157,7 +157,7 @@ impl<H: ContentValidator> ContentFetcherHandler<H> {
url: String,
control: Control,
handler: H,
embeddable_at: Option<u16>,
embeddable_on: Option<(String, u16)>,
) -> (Self, Arc<FetchControl>) {
let fetch_control = Arc::new(FetchControl::default());
@@ -169,7 +169,7 @@ impl<H: ContentValidator> ContentFetcherHandler<H> {
status: FetchState::NotStarted(url),
installer: handler,
request_url: None,
embeddable_at: embeddable_at,
embeddable_on: embeddable_on,
};
(handler, fetch_control)
@@ -208,7 +208,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Unable To Start Dapp Download",
"Could not initialize download of the dapp. It might be a problem with the remote server.",
Some(&format!("{}", e)),
self.embeddable_at,
self.embeddable_on.clone(),
)),
}
},
@@ -218,7 +218,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Method Not Allowed",
"Only <code>GET</code> requests are allowed.",
None,
self.embeddable_at,
self.embeddable_on.clone(),
)),
})
} else { None };
@@ -241,7 +241,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Download Timeout",
&format!("Could not fetch content within {} seconds.", FETCH_TIMEOUT),
None,
self.embeddable_at,
self.embeddable_on.clone(),
);
Self::close_client(&mut self.client);
(Some(FetchState::Error(timeout)), Next::write())
@@ -263,7 +263,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Invalid Dapp",
"Downloaded bundle does not contain a valid content.",
Some(&format!("{:?}", e)),
self.embeddable_at,
self.embeddable_on.clone(),
))
},
Ok((id, result)) => {
@@ -284,7 +284,7 @@ impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<
"Download Error",
"There was an error when fetching the content.",
Some(&format!("{:?}", e)),
self.embeddable_at,
self.embeddable_on.clone(),
);
(Some(FetchState::Error(error)), Next::write())
},

View File

@@ -30,18 +30,18 @@ pub use self::fetch::{ContentFetcherHandler, ContentValidator, FetchControl};
use url::Url;
use hyper::{server, header, net, uri};
use signer_address;
use address;
/// Adds security-related headers to the Response.
pub fn add_security_headers(headers: &mut header::Headers, embeddable_at: Option<u16>) {
pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Option<(String, u16)>) {
headers.set_raw("X-XSS-Protection", vec![b"1; mode=block".to_vec()]);
headers.set_raw("X-Content-Type-Options", vec![b"nosniff".to_vec()]);
// Embedding header:
if let Some(port) = embeddable_at {
if let Some(embeddable_on) = embeddable_on {
headers.set_raw(
"X-Frame-Options",
vec![format!("ALLOW-FROM http://{}", signer_address(port)).into_bytes()]
vec![format!("ALLOW-FROM http://{}", address(embeddable_on)).into_bytes()]
);
} else {
// TODO [ToDr] Should we be more strict here (DENY?)?

View File

@@ -112,7 +112,7 @@ pub struct ServerBuilder {
handler: Arc<IoHandler>,
registrar: Arc<ContractClient>,
sync_status: Arc<SyncStatus>,
signer_port: Option<u16>,
signer_address: Option<(String, u16)>,
}
impl Extendable for ServerBuilder {
@@ -129,7 +129,7 @@ impl ServerBuilder {
handler: Arc::new(IoHandler::new()),
registrar: registrar,
sync_status: Arc::new(|| false),
signer_port: None,
signer_address: None,
}
}
@@ -139,8 +139,8 @@ impl ServerBuilder {
}
/// Change default signer port.
pub fn with_signer_port(&mut self, signer_port: Option<u16>) {
self.signer_port = signer_port;
pub fn with_signer_address(&mut self, signer_address: Option<(String, u16)>) {
self.signer_address = signer_address;
}
/// Asynchronously start server with no authentication,
@@ -152,7 +152,7 @@ impl ServerBuilder {
NoAuth,
self.handler.clone(),
self.dapps_path.clone(),
self.signer_port.clone(),
self.signer_address.clone(),
self.registrar.clone(),
self.sync_status.clone(),
)
@@ -167,7 +167,7 @@ impl ServerBuilder {
HttpBasicAuth::single_user(username, password),
self.handler.clone(),
self.dapps_path.clone(),
self.signer_port.clone(),
self.signer_address.clone(),
self.registrar.clone(),
self.sync_status.clone(),
)
@@ -197,11 +197,11 @@ impl Server {
}
/// Returns a list of CORS domains for API endpoint.
fn cors_domains(signer_port: Option<u16>) -> Vec<String> {
match signer_port {
Some(port) => vec![
fn cors_domains(signer_address: Option<(String, u16)>) -> Vec<String> {
match signer_address {
Some(signer_address) => vec![
format!("http://{}{}", HOME_PAGE, DAPPS_DOMAIN),
format!("http://{}", signer_address(port)),
format!("http://{}", address(signer_address)),
],
None => vec![],
}
@@ -213,15 +213,15 @@ impl Server {
authorization: A,
handler: Arc<IoHandler>,
dapps_path: String,
signer_port: Option<u16>,
signer_address: Option<(String, u16)>,
registrar: Arc<ContractClient>,
sync_status: Arc<SyncStatus>,
) -> Result<Server, ServerError> {
let panic_handler = Arc::new(Mutex::new(None));
let authorization = Arc::new(authorization);
let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new(apps::urlhint::URLHintContract::new(registrar), sync_status, signer_port));
let endpoints = Arc::new(apps::all_endpoints(dapps_path, signer_port.clone()));
let cors_domains = Self::cors_domains(signer_port);
let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new(apps::urlhint::URLHintContract::new(registrar), sync_status, signer_address.clone()));
let endpoints = Arc::new(apps::all_endpoints(dapps_path, signer_address.clone()));
let cors_domains = Self::cors_domains(signer_address.clone());
let special = Arc::new({
let mut special = HashMap::new();
@@ -238,7 +238,7 @@ impl Server {
try!(hyper::Server::http(addr))
.handle(move |ctrl| router::Router::new(
ctrl,
signer_port.clone(),
signer_address.clone(),
content_fetcher.clone(),
endpoints.clone(),
special.clone(),
@@ -302,8 +302,8 @@ pub fn random_filename() -> String {
rng.gen_ascii_chars().take(12).collect()
}
fn signer_address(port: u16) -> String {
format!("127.0.0.1:{}", port)
fn address(address: (String, u16)) -> String {
format!("{}:{}", address.0, address.1)
}
#[cfg(test)]
@@ -332,7 +332,7 @@ mod util_tests {
// when
let none = Server::cors_domains(None);
let some = Server::cors_domains(Some(18180));
let some = Server::cors_domains(Some(("127.0.0.1".into(), 18180)));
// then
assert_eq!(none, Vec::<String>::new());

View File

@@ -25,7 +25,7 @@ pub struct PageEndpoint<T : WebApp + 'static> {
/// Prefix to strip from the path (when `None` deducted from `app_id`)
pub prefix: Option<String>,
/// Safe to be loaded in frame by other origin. (use wisely!)
safe_to_embed_at_port: Option<u16>,
safe_to_embed_on: Option<(String, u16)>,
info: EndpointInfo,
}
@@ -36,7 +36,7 @@ impl<T: WebApp + 'static> PageEndpoint<T> {
PageEndpoint {
app: Arc::new(app),
prefix: None,
safe_to_embed_at_port: None,
safe_to_embed_on: None,
info: EndpointInfo::from(info),
}
}
@@ -49,7 +49,7 @@ impl<T: WebApp + 'static> PageEndpoint<T> {
PageEndpoint {
app: Arc::new(app),
prefix: Some(prefix),
safe_to_embed_at_port: None,
safe_to_embed_on: None,
info: EndpointInfo::from(info),
}
}
@@ -57,12 +57,12 @@ impl<T: WebApp + 'static> PageEndpoint<T> {
/// Creates new `PageEndpoint` which can be safely used in iframe
/// even from different origin. It might be dangerous (clickjacking).
/// Use wisely!
pub fn new_safe_to_embed(app: T, port: Option<u16>) -> Self {
pub fn new_safe_to_embed(app: T, address: Option<(String, u16)>) -> Self {
let info = app.info();
PageEndpoint {
app: Arc::new(app),
prefix: None,
safe_to_embed_at_port: port,
safe_to_embed_on: address,
info: EndpointInfo::from(info),
}
}
@@ -79,9 +79,9 @@ impl<T: WebApp> Endpoint for PageEndpoint<T> {
app: BuiltinDapp::new(self.app.clone()),
prefix: self.prefix.clone(),
path: path,
file: handler::ServedFile::new(self.safe_to_embed_at_port.clone()),
file: handler::ServedFile::new(self.safe_to_embed_on.clone()),
cache: PageCache::Disabled,
safe_to_embed_at_port: self.safe_to_embed_at_port.clone(),
safe_to_embed_on: self.safe_to_embed_on.clone(),
})
}
}

View File

@@ -60,13 +60,13 @@ pub enum ServedFile<T: Dapp> {
}
impl<T: Dapp> ServedFile<T> {
pub fn new(embeddable_at: Option<u16>) -> Self {
pub fn new(embeddable_on: Option<(String, u16)>) -> Self {
ServedFile::Error(ContentHandler::error(
StatusCode::NotFound,
"404 Not Found",
"Requested dapp resource was not found.",
None,
embeddable_at,
embeddable_on,
))
}
}
@@ -97,7 +97,7 @@ pub struct PageHandler<T: Dapp> {
/// Requested path.
pub path: EndpointPath,
/// Flag indicating if the file can be safely embeded (put in iframe).
pub safe_to_embed_at_port: Option<u16>,
pub safe_to_embed_on: Option<(String, u16)>,
/// Cache settings for this page.
pub cache: PageCache,
}
@@ -133,7 +133,7 @@ impl<T: Dapp> server::Handler<HttpStream> for PageHandler<T> {
self.app.file(&self.extract_path(url.path()))
},
_ => None,
}.map_or_else(|| ServedFile::new(self.safe_to_embed_at_port.clone()), |f| ServedFile::File(f));
}.map_or_else(|| ServedFile::new(self.safe_to_embed_on.clone()), |f| ServedFile::File(f));
Next::write()
}
@@ -162,7 +162,7 @@ impl<T: Dapp> server::Handler<HttpStream> for PageHandler<T> {
}
// Security headers:
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_at_port);
add_security_headers(&mut res.headers_mut(), self.safe_to_embed_on.clone());
Next::write()
},
ServedFile::Error(ref mut handler) => {
@@ -246,7 +246,7 @@ fn should_extract_path_with_appid() {
},
file: ServedFile::new(None),
cache: Default::default(),
safe_to_embed_at_port: None,
safe_to_embed_on: None,
};
// when

View File

@@ -27,17 +27,17 @@ pub struct LocalPageEndpoint {
mime: Option<String>,
info: Option<EndpointInfo>,
cache: PageCache,
embeddable_at: Option<u16>,
embeddable_on: Option<(String, u16)>,
}
impl LocalPageEndpoint {
pub fn new(path: PathBuf, info: EndpointInfo, cache: PageCache, embeddable_at: Option<u16>) -> Self {
pub fn new(path: PathBuf, info: EndpointInfo, cache: PageCache, embeddable_on: Option<(String, u16)>) -> Self {
LocalPageEndpoint {
path: path,
mime: None,
info: Some(info),
cache: cache,
embeddable_at: embeddable_at,
embeddable_on: embeddable_on,
}
}
@@ -47,7 +47,7 @@ impl LocalPageEndpoint {
mime: Some(mime),
info: None,
cache: cache,
embeddable_at: None,
embeddable_on: None,
}
}
@@ -68,7 +68,7 @@ impl Endpoint for LocalPageEndpoint {
prefix: None,
path: path,
file: handler::ServedFile::new(None),
safe_to_embed_at_port: self.embeddable_at,
safe_to_embed_on: self.embeddable_on.clone(),
cache: self.cache,
})
} else {
@@ -77,7 +77,7 @@ impl Endpoint for LocalPageEndpoint {
prefix: None,
path: path,
file: handler::ServedFile::new(None),
safe_to_embed_at_port: self.embeddable_at,
safe_to_embed_on: self.embeddable_on.clone(),
cache: self.cache,
})
}

View File

@@ -19,24 +19,24 @@
use endpoint::{Endpoint, Handler, EndpointPath};
use handlers::ContentHandler;
use apps::{HOME_PAGE, DAPPS_DOMAIN};
use signer_address;
use address;
pub struct ProxyPac {
signer_port: Option<u16>,
signer_address: Option<(String, u16)>,
}
impl ProxyPac {
pub fn boxed(signer_port: Option<u16>) -> Box<Endpoint> {
pub fn boxed(signer_address: Option<(String, u16)>) -> Box<Endpoint> {
Box::new(ProxyPac {
signer_port: signer_port
signer_address: signer_address
})
}
}
impl Endpoint for ProxyPac {
fn to_handler(&self, path: EndpointPath) -> Box<Handler> {
let signer = self.signer_port
.map(signer_address)
let signer = self.signer_address.clone()
.map(address)
.unwrap_or_else(|| format!("{}:{}", path.host, path.port));
let content = format!(

View File

@@ -20,7 +20,7 @@
pub mod auth;
mod host_validation;
use signer_address;
use address;
use std::sync::Arc;
use std::collections::HashMap;
use url::{Url, Host};
@@ -43,7 +43,7 @@ pub enum SpecialEndpoint {
pub struct Router<A: Authorization + 'static> {
control: Option<Control>,
signer_port: Option<u16>,
signer_address: Option<(String, u16)>,
endpoints: Arc<Endpoints>,
fetch: Arc<ContentFetcher>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
@@ -117,22 +117,22 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
"404 Not Found",
"Requested content was not found.",
None,
self.signer_port,
self.signer_address.clone(),
))
},
// Redirect any other GET request to signer.
_ if *req.method() == hyper::Method::Get => {
if let Some(port) = self.signer_port {
if let Some(signer_address) = self.signer_address.clone() {
trace!(target: "dapps", "Redirecting to signer interface.");
Redirection::boxed(&format!("http://{}", signer_address(port)))
Redirection::boxed(&format!("http://{}", address(signer_address)))
} else {
trace!(target: "dapps", "Signer disabled, returning 404.");
Box::new(ContentHandler::error(
StatusCode::NotFound,
"404 Not Found",
"Your homepage is not available when Trusted Signer is disabled.",
Some("You can still access dapps by writing a correct address, though. Re-enabled Signer to get your homepage back."),
self.signer_port,
Some("You can still access dapps by writing a correct address, though. Re-enable Signer to get your homepage back."),
self.signer_address.clone(),
))
}
},
@@ -168,7 +168,7 @@ impl<A: Authorization + 'static> server::Handler<HttpStream> for Router<A> {
impl<A: Authorization> Router<A> {
pub fn new(
control: Control,
signer_port: Option<u16>,
signer_address: Option<(String, u16)>,
content_fetcher: Arc<ContentFetcher>,
endpoints: Arc<Endpoints>,
special: Arc<HashMap<SpecialEndpoint, Box<Endpoint>>>,
@@ -181,7 +181,7 @@ impl<A: Authorization> Router<A> {
.to_handler(EndpointPath::default());
Router {
control: Some(control),
signer_port: signer_port,
signer_address: signer_address,
endpoints: endpoints,
fetch: content_fetcher,
special: special,

View File

@@ -76,7 +76,7 @@ pub fn init_server(hosts: Option<Vec<String>>, is_syncing: bool) -> (Server, Arc
dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading");
let mut builder = ServerBuilder::new(dapps_path.to_str().unwrap().into(), registrar.clone());
builder.with_sync_status(Arc::new(move || is_syncing));
builder.with_signer_port(Some(SIGNER_PORT));
builder.with_signer_address(Some(("127.0.0.1".into(), SIGNER_PORT)));
(
builder.start_unsecured_http(&"127.0.0.1:0".parse().unwrap(), hosts).unwrap(),
registrar,
@@ -89,7 +89,7 @@ pub fn serve_with_auth(user: &str, pass: &str) -> Server {
let mut dapps_path = env::temp_dir();
dapps_path.push("non-existent-dir-to-prevent-fs-files-from-loading");
let mut builder = ServerBuilder::new(dapps_path.to_str().unwrap().into(), registrar);
builder.with_signer_port(Some(SIGNER_PORT));
builder.with_signer_address(Some(("127.0.0.1".into(), SIGNER_PORT)));
builder.start_basic_auth_http(&"127.0.0.1:0".parse().unwrap(), None, user, pass).unwrap()
}

View File

@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::thread;
use std::time::Duration;
use std::io::{Read, Write};
use std::str::{self, Lines};
@@ -42,8 +43,28 @@ pub fn read_block(lines: &mut Lines, all: bool) -> String {
block
}
fn connect(address: &SocketAddr) -> TcpStream {
let mut retries = 0;
let mut last_error = None;
while retries < 10 {
retries += 1;
let res = TcpStream::connect(address);
match res {
Ok(stream) => {
return stream;
},
Err(e) => {
last_error = Some(e);
thread::sleep(Duration::from_millis(retries * 10));
}
}
}
panic!("Unable to connect to the server. Last error: {:?}", last_error);
}
pub fn request(address: &SocketAddr, request: &str) -> Response {
let mut req = TcpStream::connect(address).unwrap();
let mut req = connect(address);
req.set_read_timeout(Some(Duration::from_secs(1))).unwrap();
req.write_all(request.as_bytes()).unwrap();

View File

@@ -131,10 +131,11 @@
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
],
"eip150Transition": "0x259518",
"eip155Transition": 2642462,
"eip160Transition": 2642462,
"eip161abcTransition": 2642462,
"eip161dTransition": 2642462
"eip155Transition": 2675000,
"eip160Transition": 2675000,
"eip161abcTransition": 2675000,
"eip161dTransition": 2675000,
"maxCodeSize": 24576
}
}
},
@@ -176,7 +177,13 @@
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50: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@10.6.6.117:30303",
"enode://fe11ef89fc5ac9da358fc160857855f25bbf9e332c79b9ca7089330c02b728b2349988c6062f10982041702110745e203d26975a6b34bcc97144f9fe439034e8@10.1.72.117:30303"
],
"accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },

View File

@@ -11,10 +11,10 @@
"registrar": "0x52dff57a8a1532e6afb3dc07e2af58bb9eb05b3d",
"homesteadTransition": "0x789b0",
"eip150Transition": "0x1b34d8",
"eip155Transition": "0x7fffffffffffffff",
"eip160Transition": "0x7fffffffffffffff",
"eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff"
"eip155Transition": 1885000,
"eip160Transition": 1885000,
"eip161abcTransition": 1885000,
"eip161dTransition": 1885000
}
}
},

View File

@@ -1050,7 +1050,9 @@ impl BlockChainClient for Client {
transaction_hash: transaction_hash.clone(),
transaction_index: transaction_index,
log_index: i
}).collect()
}).collect(),
log_bloom: receipt.log_bloom,
state_root: receipt.state_root,
})
},
_ => None
@@ -1222,8 +1224,7 @@ impl BlockChainClient for Client {
fn uncle_extra_info(&self, id: UncleID) -> Option<BTreeMap<String, String>> {
self.uncle(id)
.map(|block| BlockView::new(&block).header())
.map(|header| self.engine.extra_info(&header))
.map(|header| self.engine.extra_info(&decode(&header)))
}
}

View File

@@ -315,7 +315,7 @@ pub fn get_temp_state_db() -> GuardedTempResult<StateDB> {
impl MiningBlockChainClient for TestBlockChainClient {
fn latest_schedule(&self) -> Schedule {
Schedule::new_post_eip150(true, true, true)
Schedule::new_post_eip150(24576, true, true, true)
}
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock {

View File

@@ -55,7 +55,7 @@ impl Engine for InstantSeal {
}
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
Schedule::new_homestead()
Schedule::new_post_eip150(usize::max_value(), false, false, false)
}
fn is_sealer(&self, _author: &Address) -> Option<bool> { Some(true) }

View File

@@ -70,6 +70,8 @@ pub struct EthashParams {
pub eip161abc_transition: u64,
/// Number of first block where EIP-161.d begins.
pub eip161d_transition: u64,
/// Maximum amount of code that can be deploying into a contract.
pub max_code_size: u64,
}
impl From<ethjson::spec::EthashParams> for EthashParams {
@@ -83,17 +85,18 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
block_reward: p.block_reward.into(),
registrar: p.registrar.map_or_else(Address::new, Into::into),
homestead_transition: p.homestead_transition.map_or(0, Into::into),
dao_hardfork_transition: p.dao_hardfork_transition.map_or(0x7fffffffffffffff, Into::into),
dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into),
dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::new, Into::into),
dao_hardfork_accounts: p.dao_hardfork_accounts.unwrap_or_else(Vec::new).into_iter().map(Into::into).collect(),
difficulty_hardfork_transition: p.difficulty_hardfork_transition.map_or(0x7fffffffffffffff, Into::into),
difficulty_hardfork_transition: p.difficulty_hardfork_transition.map_or(u64::max_value(), Into::into),
difficulty_hardfork_bound_divisor: p.difficulty_hardfork_bound_divisor.map_or(p.difficulty_bound_divisor.into(), Into::into),
bomb_defuse_transition: p.bomb_defuse_transition.map_or(0x7fffffffffffffff, Into::into),
bomb_defuse_transition: p.bomb_defuse_transition.map_or(u64::max_value(), Into::into),
eip150_transition: p.eip150_transition.map_or(0, Into::into),
eip155_transition: p.eip155_transition.map_or(0, Into::into),
eip160_transition: p.eip160_transition.map_or(0, Into::into),
eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into),
eip161d_transition: p.eip161d_transition.map_or(0x7fffffffffffffff, Into::into),
eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into),
max_code_size: p.max_code_size.map_or(u64::max_value(), Into::into),
}
}
}
@@ -146,6 +149,7 @@ impl Engine for Ethash {
Schedule::new_homestead()
} else {
Schedule::new_post_eip150(
self.ethash_params.max_code_size as usize,
env_info.number >= self.ethash_params.eip160_transition,
env_info.number >= self.ethash_params.eip161abc_transition,
env_info.number >= self.ethash_params.eip161d_transition

View File

@@ -70,6 +70,8 @@ pub struct Schedule {
pub quad_coeff_div: usize,
/// Cost for contract length when executing `CREATE`
pub create_data_gas: usize,
/// Maximum code size when creating a contract.
pub create_data_limit: usize,
/// Transaction cost
pub tx_gas: usize,
/// `CREATE` transaction cost
@@ -111,7 +113,7 @@ impl Schedule {
}
/// Schedule for the post-EIP-150-era of the Ethereum main net.
pub fn new_post_eip150(fix_exp: bool, no_empty: bool, kill_empty: bool) -> Schedule {
pub fn new_post_eip150(max_code_size: usize, fix_exp: bool, no_empty: bool, kill_empty: bool) -> Schedule {
Schedule {
exceptional_failed_code_deposit: true,
have_delegate_call: true,
@@ -139,6 +141,7 @@ impl Schedule {
memory_gas: 3,
quad_coeff_div: 512,
create_data_gas: 200,
create_data_limit: max_code_size,
tx_gas: 21000,
tx_create_gas: 53000,
tx_data_zero_gas: 4,
@@ -183,6 +186,7 @@ impl Schedule {
memory_gas: 3,
quad_coeff_div: 512,
create_data_gas: 200,
create_data_limit: usize::max_value(),
tx_gas: 21000,
tx_create_gas: tcg,
tx_data_zero_gas: 4,

View File

@@ -242,7 +242,7 @@ impl<'a, T, V> Ext for Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMT
},
OutputPolicy::InitContract(ref mut copy) => {
let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas);
if return_cost > *gas {
if return_cost > *gas || data.len() > self.schedule.create_data_limit {
return match self.schedule.exceptional_failed_code_deposit {
true => Err(evm::Error::OutOfGas),
false => Ok(*gas)

View File

@@ -26,8 +26,7 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
let old_schedule = evm::Schedule::new_frontier();
let new_schedule = evm::Schedule::new_homestead();
for (name, test) in tests.into_iter() {
let mut fail = false;
let mut fail_unless = |cond: bool| if !cond && !fail { failed.push(name.clone()); println!("Transaction failed: {:?}", name); fail = true };
let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); };
let number: Option<u64> = test.block_number.map(Into::into);
let schedule = match number {
@@ -35,7 +34,7 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
Some(x) if x < 1_150_000 => &old_schedule,
Some(_) => &new_schedule
};
let allow_network_id_of_one = number.map_or(false, |n| n > 2600000);
let allow_network_id_of_one = number.map_or(false, |n| n >= 3_500_000);
let rlp: Vec<u8> = test.rlp.into();
let res = UntrustedRlp::new(&rlp)
@@ -43,26 +42,26 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
.map_err(From::from)
.and_then(|t: SignedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one));
fail_unless(test.transaction.is_none() == res.is_err());
fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
let t = res.unwrap();
fail_unless(t.sender().unwrap() == sender.into());
fail_unless(t.sender().unwrap() == sender.into(), "sender mismatch");
let is_acceptable_network_id = match t.network_id() {
None => true,
Some(1) if allow_network_id_of_one => true,
_ => false,
};
fail_unless(is_acceptable_network_id);
fail_unless(is_acceptable_network_id, "Network ID unacceptable");
let data: Vec<u8> = tx.data.into();
fail_unless(t.data == data);
fail_unless(t.gas_price == tx.gas_price.into());
fail_unless(t.nonce == tx.nonce.into());
fail_unless(t.value == tx.value.into());
fail_unless(t.data == data, "data mismatch");
fail_unless(t.gas_price == tx.gas_price.into(), "gas_price mismatch");
fail_unless(t.nonce == tx.nonce.into(), "nonce mismatch");
fail_unless(t.value == tx.value.into(), "value mismatch");
let to: Option<ethjson::hash::Address> = tx.to.into();
let to: Option<Address> = to.map(Into::into);
match t.action {
Action::Call(dest) => fail_unless(Some(dest) == to),
Action::Create => fail_unless(None == to),
Action::Call(dest) => fail_unless(Some(dest) == to, "call/destination mismatch"),
Action::Create => fail_unless(None == to, "create mismatch"),
}
}
}
@@ -80,3 +79,7 @@ declare_test!{TransactionTests_Homestead_ttTransactionTest, "TransactionTests/Ho
declare_test!{heavy => TransactionTests_Homestead_tt10mbDataField, "TransactionTests/Homestead/tt10mbDataField"}
declare_test!{TransactionTests_Homestead_ttWrongRLPTransaction, "TransactionTests/Homestead/ttWrongRLPTransaction"}
declare_test!{TransactionTests_RandomTests_tr201506052141PYTHON, "TransactionTests/RandomTests/tr201506052141PYTHON"}
declare_test!{TransactionTests_Homestead_ttTransactionTestEip155VitaliksTests, "TransactionTests/Homestead/ttTransactionTestEip155VitaliksTests"}
declare_test!{TransactionTests_EIP155_ttTransactionTest, "TransactionTests/EIP155/ttTransactionTest"}
declare_test!{TransactionTests_EIP155_ttTransactionTestEip155VitaliksTests, "TransactionTests/EIP155/ttTransactionTestEip155VitaliksTests"}
declare_test!{TransactionTests_EIP155_ttTransactionTestVRule, "TransactionTests/EIP155/ttTransactionTestVRule"}

View File

@@ -935,6 +935,8 @@ impl MinerService for Miner {
}
},
logs: receipt.logs.clone(),
log_bloom: receipt.log_bloom,
state_root: receipt.state_root,
}
})
}

View File

@@ -19,11 +19,11 @@
use account_db::{AccountDB, AccountDBMut};
use snapshot::Error;
use util::{U256, FixedHash, H256, Bytes, HashDB, DBValue, SHA3_EMPTY, SHA3_NULL_RLP};
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY, SHA3_NULL_RLP};
use util::trie::{TrieDB, Trie};
use rlp::{Rlp, RlpStream, Stream, UntrustedRlp, View};
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
// An empty account -- these are replaced with RLP null data for a space optimization.
const ACC_EMPTY: Account = Account {
@@ -150,7 +150,6 @@ impl Account {
pub fn from_fat_rlp(
acct_db: &mut AccountDBMut,
rlp: UntrustedRlp,
code_map: &HashMap<H256, Bytes>,
) -> Result<(Self, Option<Bytes>), Error> {
use util::{TrieDBMut, TrieMut};
@@ -177,9 +176,6 @@ impl Account {
}
CodeState::Hash => {
let code_hash = try!(rlp.val_at(3));
if let Some(code) = code_map.get(&code_hash) {
acct_db.emplace(code_hash.clone(), DBValue::from_slice(code));
}
(code_hash, None)
}
@@ -229,7 +225,7 @@ mod tests {
use util::{Address, FixedHash, H256, HashDB, DBValue};
use rlp::{UntrustedRlp, View};
use std::collections::{HashSet, HashMap};
use std::collections::HashSet;
use super::{ACC_EMPTY, Account};
@@ -250,7 +246,7 @@ mod tests {
let fat_rlp = account.to_fat_rlp(&AccountDB::new(db.as_hashdb(), &addr), &mut Default::default()).unwrap();
let fat_rlp = UntrustedRlp::new(&fat_rlp);
assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, &Default::default()).unwrap().0, account);
assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp).unwrap().0, account);
}
#[test]
@@ -275,7 +271,7 @@ mod tests {
let fat_rlp = account.to_fat_rlp(&AccountDB::new(db.as_hashdb(), &addr), &mut Default::default()).unwrap();
let fat_rlp = UntrustedRlp::new(&fat_rlp);
assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, &Default::default()).unwrap().0, account);
assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp).unwrap().0, account);
}
#[test]
@@ -318,12 +314,11 @@ mod tests {
let fat_rlp1 = UntrustedRlp::new(&fat_rlp1);
let fat_rlp2 = UntrustedRlp::new(&fat_rlp2);
let code_map = HashMap::new();
let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2, &code_map).unwrap();
let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2).unwrap();
assert!(maybe_code.is_none());
assert_eq!(acc, account2);
let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr1), fat_rlp1, &code_map).unwrap();
let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr1), fat_rlp1).unwrap();
assert_eq!(maybe_code, Some(b"this is definitely code".to_vec()));
assert_eq!(acc, account1);
}
@@ -332,9 +327,8 @@ mod tests {
fn encoding_empty_acc() {
let mut db = get_temp_state_db();
let mut used_code = HashSet::new();
let code_map = HashMap::new();
assert_eq!(ACC_EMPTY.to_fat_rlp(&AccountDB::new(db.as_hashdb(), &Address::default()), &mut used_code).unwrap(), ::rlp::NULL_RLP.to_vec());
assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), UntrustedRlp::new(&::rlp::NULL_RLP), &code_map).unwrap(), (ACC_EMPTY, None));
assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), UntrustedRlp::new(&::rlp::NULL_RLP)).unwrap(), (ACC_EMPTY, None));
}
}

View File

@@ -389,7 +389,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex<SnapshotWriter +
pub struct StateRebuilder {
db: Box<JournalDB>,
state_root: H256,
code_map: HashMap<H256, Bytes>, // maps code hashes to code itself.
known_code: HashMap<H256, H256>, // code hashes mapped to first account with this code.
missing_code: HashMap<H256, Vec<H256>>, // maps code hashes to lists of accounts missing that code.
bloom: Bloom,
}
@@ -400,7 +400,7 @@ impl StateRebuilder {
StateRebuilder {
db: journaldb::new(db.clone(), pruning, ::db::COL_STATE),
state_root: SHA3_NULL_RLP,
code_map: HashMap::new(),
known_code: HashMap::new(),
missing_code: HashMap::new(),
bloom: StateDB::load_bloom(&*db),
}
@@ -419,24 +419,26 @@ impl StateRebuilder {
let chunk_size = account_fat_rlps.len() / ::num_cpus::get() + 1;
// new code contained within this chunk.
let mut chunk_code = HashMap::new();
let mut chunk_code = Vec::new();
for (account_chunk, out_pairs_chunk) in account_fat_rlps.chunks(chunk_size).zip(pairs.chunks_mut(chunk_size)) {
let code_map = &self.code_map;
let status = try!(rebuild_accounts(self.db.as_hashdb_mut(), account_chunk, out_pairs_chunk, code_map));
let status = try!(rebuild_accounts(self.db.as_hashdb_mut(), account_chunk, out_pairs_chunk, &self.known_code));
chunk_code.extend(status.new_code);
// update missing code.
for (addr_hash, code_hash) in status.missing_code {
self.missing_code.entry(code_hash).or_insert_with(Vec::new).push(addr_hash);
}
}
// patch up all missing code. must be done after collecting all new missing code entries.
for (code_hash, code) in chunk_code {
for (code_hash, code, first_with) in chunk_code {
for addr_hash in self.missing_code.remove(&code_hash).unwrap_or_else(Vec::new) {
let mut db = AccountDBMut::from_hash(self.db.as_hashdb_mut(), addr_hash);
db.emplace(code_hash, DBValue::from_slice(&code));
}
self.code_map.insert(code_hash, code);
self.known_code.insert(code_hash, first_with);
}
let backing = self.db.backing().clone();
@@ -482,7 +484,8 @@ impl StateRebuilder {
#[derive(Default)]
struct RebuiltStatus {
new_code: Vec<(H256, Bytes)>, // new code that's become available.
// new code that's become available. (code_hash, code, addr_hash)
new_code: Vec<(H256, Bytes, H256)>,
missing_code: Vec<(H256, H256)>, // accounts that are missing code.
}
@@ -492,9 +495,8 @@ fn rebuild_accounts(
db: &mut HashDB,
account_chunk: &[&[u8]],
out_chunk: &mut [(H256, Bytes)],
code_map: &HashMap<H256, Bytes>
) -> Result<RebuiltStatus, ::error::Error>
{
known_code: &HashMap<H256, H256>,
) -> Result<RebuiltStatus, ::error::Error> {
let mut status = RebuiltStatus::default();
for (account_pair, out) in account_chunk.into_iter().zip(out_chunk) {
let account_rlp = UntrustedRlp::new(account_pair);
@@ -503,17 +505,33 @@ fn rebuild_accounts(
let fat_rlp = try!(account_rlp.at(1));
let thin_rlp = {
let mut acct_db = AccountDBMut::from_hash(db, hash);
// fill out the storage trie and code while decoding.
let (acc, maybe_code) = try!(Account::from_fat_rlp(&mut acct_db, fat_rlp, code_map));
let (acc, maybe_code) = {
let mut acct_db = AccountDBMut::from_hash(db, hash);
try!(Account::from_fat_rlp(&mut acct_db, fat_rlp))
};
let code_hash = acc.code_hash().clone();
match maybe_code {
Some(code) => status.new_code.push((code_hash, code)),
// new inline code
Some(code) => status.new_code.push((code_hash, code, hash)),
None => {
if code_hash != ::util::SHA3_EMPTY && !code_map.contains_key(&code_hash) {
status.missing_code.push((hash, code_hash));
if code_hash != ::util::SHA3_EMPTY {
// see if this code has already been included inline
match known_code.get(&code_hash) {
Some(&first_with) => {
// if so, load it from the database.
let code = try!(AccountDB::from_hash(db, first_with)
.get(&code_hash)
.ok_or_else(|| Error::MissingCode(vec![first_with])));
// and write it again under a different mangled key
AccountDBMut::from_hash(db, hash).emplace(code_hash, code);
}
// if not, queue it up to be filled later
None => status.missing_code.push((hash, code_hash)),
}
}
}
}

View File

@@ -17,6 +17,7 @@
//! State snapshotting tests.
use snapshot::{chunk_state, Progress, StateRebuilder};
use snapshot::account::Account;
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
use super::helpers::{compare_dbs, StateProducer};
@@ -28,6 +29,8 @@ use util::memorydb::MemoryDB;
use util::Mutex;
use devtools::RandomTempPath;
use util::sha3::SHA3_NULL_RLP;
use std::sync::Arc;
#[test]
@@ -82,3 +85,54 @@ fn snap_and_restore() {
compare_dbs(&old_db, new_db.as_hashdb());
}
#[test]
fn get_code_from_prev_chunk() {
use std::collections::HashSet;
use rlp::{RlpStream, Stream};
use util::{HashDB, H256, FixedHash, U256, Hashable};
use account_db::{AccountDBMut, AccountDB};
let code = b"this is definitely code";
let mut used_code = HashSet::new();
let mut acc_stream = RlpStream::new_list(4);
acc_stream.append(&U256::default())
.append(&U256::default())
.append(&SHA3_NULL_RLP)
.append(&code.sha3());
let (h1, h2) = (H256::random(), H256::random());
// two accounts with the same code, one per chunk.
// first one will have code inlined,
// second will just have its hash.
let thin_rlp = acc_stream.out();
let acc1 = Account::from_thin_rlp(&thin_rlp);
let acc2 = Account::from_thin_rlp(&thin_rlp);
let mut make_chunk = |acc: Account, hash| {
let mut db = MemoryDB::new();
AccountDBMut::from_hash(&mut db, hash).insert(&code[..]);
let fat_rlp = acc.to_fat_rlp(&AccountDB::from_hash(&db, hash), &mut used_code).unwrap();
let mut stream = RlpStream::new_list(1);
stream.begin_list(2).append(&hash).append_raw(&fat_rlp, 1);
stream.out()
};
let chunk1 = make_chunk(acc1, h1);
let chunk2 = make_chunk(acc2, h2);
let db_path = RandomTempPath::create_dir();
let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS);
let new_db = Arc::new(Database::open(&db_cfg, &db_path.to_string_lossy()).unwrap());
let mut rebuilder = StateRebuilder::new(new_db, Algorithm::Archive);
rebuilder.feed(&chunk1).unwrap();
rebuilder.feed(&chunk2).unwrap();
rebuilder.check_missing().unwrap();
}

View File

@@ -93,6 +93,10 @@ pub struct RichReceipt {
pub contract_address: Option<Address>,
/// Logs
pub logs: Vec<LogEntry>,
/// Logs bloom
pub log_bloom: LogBloom,
/// State root
pub state_root: H256,
}
/// Receipt with additional info.
@@ -114,6 +118,10 @@ pub struct LocalizedReceipt {
pub contract_address: Option<Address>,
/// Logs
pub logs: Vec<LocalizedLogEntry>,
/// Logs bloom
pub log_bloom: LogBloom,
/// State root
pub state_root: H256,
}
#[test]

View File

@@ -60,6 +60,11 @@ export default class Parity {
.then(outNumber);
}
dappsInterface () {
return this._transport
.execute('parity_dappsInterface');
}
defaultExtraData () {
return this._transport
.execute('parity_defaultExtraData');

View File

@@ -148,7 +148,7 @@ export default class Deployment extends Component {
addresses={ addresses }
onChange={ this.onChangeFrom } />
<div className={ styles.hint }>
the owner account to eploy from
the owner account to deploy from
</div>
</div>
<div className={ nameError ? error : styles.input }>

View File

@@ -70,7 +70,8 @@ export default class AccountSelector extends Component {
static propTypes = {
list: PropTypes.array.isRequired,
selected: PropTypes.object.isRequired,
handleSetSelected: PropTypes.func.isRequired
handleSetSelected: PropTypes.func.isRequired,
onAccountChange: PropTypes.func
};
state = {
@@ -85,7 +86,8 @@ export default class AccountSelector extends Component {
nestedItems={ nestedAccounts }
open={ this.state.open }
onSelectAccount={ this.onToggleOpen }
autoGenerateNestedIndicator={ false } />
autoGenerateNestedIndicator={ false }
nestedListStyle={ { maxHeight: '14em', overflow: 'auto' } } />
);
return (
@@ -110,6 +112,10 @@ export default class AccountSelector extends Component {
onToggleOpen = () => {
this.setState({ open: !this.state.open });
if (typeof this.props.onAccountChange === 'function') {
this.props.onAccountChange();
}
}
onSelectAccount = (address) => {

View File

@@ -21,7 +21,7 @@ import { Dialog, FlatButton } from 'material-ui';
import AccountSelector from '../../Accounts/AccountSelector';
import InputText from '../../Inputs/Text';
import { TOKEN_ADDRESS_TYPE, TLA_TYPE, UINT_TYPE, STRING_TYPE } from '../../Inputs/validation';
import { TOKEN_ADDRESS_TYPE, TLA_TYPE, DECIMAL_TYPE, STRING_TYPE } from '../../Inputs/validation';
import styles from '../actions.css';
@@ -41,11 +41,11 @@ const initState = {
floatingLabelText: 'Token TLA',
hintText: 'The token short name (3 characters)'
},
base: {
decimals: {
...defaultField,
type: UINT_TYPE,
floatingLabelText: 'Token Base',
hintText: 'The token precision'
type: DECIMAL_TYPE,
floatingLabelText: 'Token Decimals',
hintText: 'The number of decimals (0-18)'
},
name: {
...defaultField,
@@ -81,6 +81,7 @@ export default class RegisterAction extends Component {
className={ styles.dialog }
onRequestClose={ this.onClose }
actions={ this.renderActions() }
ref='dialog'
autoScrollBodyContent
>
{ this.renderContent() }
@@ -149,7 +150,9 @@ export default class RegisterAction extends Component {
renderForm () {
return (
<div>
<AccountSelector />
<AccountSelector
onAccountChange={ this.onAccountChange }
/>
{ this.renderInputs() }
</div>
);
@@ -175,6 +178,11 @@ export default class RegisterAction extends Component {
});
}
onAccountChange = () => {
const { dialog } = this.refs;
dialog.forceUpdate();
}
onChange (fieldKey, valid, value) {
const { fields } = this.state;
const field = fields[fieldKey];

View File

@@ -47,7 +47,8 @@ export const registerToken = (tokenData) => (dispatch, getState) => {
const contractInstance = state.status.contract.instance;
const fee = state.status.contract.fee;
const { address, base, name, tla } = tokenData;
const { address, decimals, name, tla } = tokenData;
const base = Math.pow(10, decimals);
dispatch(setRegisterSending(true));

View File

@@ -32,6 +32,7 @@ export const SIMPLE_TOKEN_ADDRESS_TYPE = 'SIMPLE_TOKEN_ADDRESS_TYPE';
export const TLA_TYPE = 'TLA_TYPE';
export const SIMPLE_TLA_TYPE = 'SIMPLE_TLA_TYPE';
export const UINT_TYPE = 'UINT_TYPE';
export const DECIMAL_TYPE = 'DECIMAL_TYPE';
export const STRING_TYPE = 'STRING_TYPE';
export const HEX_TYPE = 'HEX_TYPE';
export const URL_TYPE = 'URL_TYPE';
@@ -39,6 +40,7 @@ export const URL_TYPE = 'URL_TYPE';
export const ERRORS = {
invalidTLA: 'The TLA should be 3 characters long',
invalidUint: 'Please enter a non-negative integer',
invalidDecimal: 'Please enter a value between 0 and 18',
invalidString: 'Please enter at least a character',
invalidAccount: 'Please select an account to transact with',
invalidRecipient: 'Please select an account to send to',
@@ -75,7 +77,7 @@ const validateTokenAddress = (address, contract, simple) => {
return getTokenTotalSupply(address)
.then(balance => {
if (balance === null) {
if (balance === null || balance.equals(0)) {
return {
error: ERRORS.invalidTokenAddress,
valid: false
@@ -152,6 +154,21 @@ const validateUint = (uint) => {
};
};
const validateDecimal = (decimal) => {
if (!/^\d+$/.test(decimal) || parseInt(decimal) < 0 || parseInt(decimal) > 18) {
return {
error: ERRORS.invalidDecimal,
valid: false
};
}
return {
value: parseInt(decimal),
error: null,
valid: true
};
};
const validateString = (string) => {
if (string.toString().length === 0) {
return {
@@ -204,6 +221,7 @@ export const validate = (value, type, contract) => {
if (type === TLA_TYPE) return validateTLA(value, contract);
if (type === SIMPLE_TLA_TYPE) return validateTLA(value, contract, true);
if (type === UINT_TYPE) return validateUint(value);
if (type === DECIMAL_TYPE) return validateDecimal(value);
if (type === STRING_TYPE) return validateString(value);
if (type === HEX_TYPE) return validateHex(value);
if (type === URL_TYPE) return validateURL(value);

View File

@@ -57,6 +57,7 @@ export default class Token extends Component {
isLoading: PropTypes.bool,
isPending: PropTypes.bool,
isTokenOwner: PropTypes.bool.isRequired,
isContractOwner: PropTypes.bool.isRequired,
fullWidth: PropTypes.bool
};
@@ -151,8 +152,8 @@ export default class Token extends Component {
if (!base || base < 0) return null;
return (
<Chip
value={ base.toString() }
label='Base' />
value={ Math.log10(base).toString() }
label='Decimals' />
);
}
@@ -220,7 +221,7 @@ export default class Token extends Component {
}
renderUnregister () {
if (!this.props.isTokenOwner) {
if (!this.props.isContractOwner) {
return null;
}

View File

@@ -45,7 +45,7 @@ export default class Tokens extends Component {
}
renderTokens (tokens) {
const { accounts } = this.props;
const { accounts, isOwner } = this.props;
return tokens.map((token, index) => {
if (!token || !token.tla) {
@@ -61,7 +61,8 @@ export default class Tokens extends Component {
handleMetaLookup={ this.props.handleMetaLookup }
handleAddMeta={ this.props.handleAddMeta }
key={ index }
isTokenOwner={ isTokenOwner } />
isTokenOwner={ isTokenOwner }
isContractOwner={ isOwner } />
);
});
}

View File

@@ -59,6 +59,8 @@ const store = initStore(api);
store.dispatch({ type: 'initAll', api });
store.dispatch(setApi(api));
window.secureApi = api;
const routerHistory = useRouterHistory(createHashHistory)({});
ReactDOM.render(

View File

@@ -109,6 +109,15 @@ export default {
}
},
dappsInterface: {
desc: 'Returns the interface the dapps are running on, error if not enabled',
params: [],
returns: {
type: String,
desc: 'The interface'
}
},
defaultExtraData: {
desc: 'Returns the default extra data',
params: [],

View File

@@ -58,7 +58,7 @@ export default class AccountDetails extends Component {
readOnly
allowCopy
hint='the account recovery phrase'
label='account recovery phrase (keep safe)'
label='owner recovery phrase (keep private and secure, it allows full and unlimited access to the account)'
value={ phrase } />
);
}

View File

@@ -314,7 +314,7 @@ export default class Transfer extends Component {
}
const token = balance.tokens.find((balance) => balance.token.tag === tag).token;
const s = new BigNumber(num).mul(token.format || 1).toString();
const s = new BigNumber(num).mul(token.format || 1).toFixed();
if (s.indexOf('.') !== -1) {
return ERRORS.invalidDecimals;
@@ -516,6 +516,13 @@ export default class Transfer extends Component {
}
recalculateGas = () => {
if (!this.isValid()) {
this.setState({
gas: '0'
}, this.recalculate);
return;
}
(this.state.isEth
? this._estimateGasEth()
: this._estimateGasToken()

View File

@@ -85,11 +85,6 @@ export default class Status {
setTimeout(this._pollStatus, timeout);
};
const wasConnected = this._store.getState().nodeStatus.isConnected;
if (isConnected !== wasConnected) {
this._fetchEnode();
}
this._store.dispatch(statusCollection({ isConnected, isConnecting, needsToken, secureToken }));
if (!isConnected) {
@@ -111,8 +106,7 @@ export default class Status {
this._api.parity.netPort(),
this._api.parity.nodeName(),
this._api.parity.rpcSettings(),
this._api.eth.syncing(),
this._pollTraceMode()
this._api.eth.syncing()
])
.then(([clientVersion, coinbase, defaultExtraData, extraData, gasFloorTarget, hashrate, minGasPrice, netChain, netPeers, netPort, nodeName, rpcSettings, syncing, traceMode]) => {
const isTest = netChain === 'morden' || netChain === 'testnet';
@@ -134,12 +128,12 @@ export default class Status {
isTest,
traceMode
}));
nextTimeout();
})
.catch((error) => {
console.error('_pollStatus', error);
nextTimeout();
});
nextTimeout();
}
_pollLogs = () => {

View File

@@ -23,7 +23,7 @@ export default class SecureApi extends Api {
super(new Api.Transport.Ws(url, sysuiToken));
this._isConnecting = true;
this._connectState = 0;
this._connectState = sysuiToken === 'initial' ? 1 : 0;
this._needsToken = false;
this._dappsPort = 8080;
this._signerPort = 8180;
@@ -110,7 +110,7 @@ export default class SecureApi extends Api {
console.log('SecureApi:connectSuccess', this._transport.token);
}
updateToken (token, connectState) {
updateToken (token, connectState = 0) {
this._connectState = connectState;
this._transport.updateToken(token.replace(/[^a-zA-Z0-9]/g, ''));
this._followConnection();
@@ -122,7 +122,7 @@ export default class SecureApi extends Api {
}
get dappsUrl () {
return `http://127.0.0.1:${this._dappsPort}`;
return `http://${window.location.hostname}:${this._dappsPort}`;
}
get signerPort () {

View File

@@ -44,7 +44,7 @@
}
.balanceValue {
margin: 0 1em 0 0;
margin: 0 0.5em 0 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;

View File

@@ -44,15 +44,30 @@ class Balance extends Component {
.filter((balance) => new BigNumber(balance.value).gt(0))
.map((balance) => {
const token = balance.token;
const value = token.format
? new BigNumber(balance.value).div(new BigNumber(token.format)).toFormat(3)
: api.util.fromWei(balance.value).toFormat(3);
let value;
if (token.format) {
const bnf = new BigNumber(token.format);
let decimals = 0;
if (bnf.gte(1000)) {
decimals = 3;
} else if (bnf.gte(100)) {
decimals = 2;
} else if (bnf.gte(10)) {
decimals = 1;
}
value = new BigNumber(balance.value).div(bnf).toFormat(decimals);
} else {
value = api.util.fromWei(balance.value).toFormat(3);
}
let imagesrc = token.image;
if (!imagesrc) {
imagesrc =
images[token.address]
? `${api.dappsUrl}${images[token.address]}`
: unknownImage;
imagesrc = images[token.address]
? `${api.dappsUrl}${images[token.address]}`
: unknownImage;
}
return (

View File

@@ -48,9 +48,7 @@ class Transactions extends Component {
}
componentDidMount () {
if (this.props.traceMode !== undefined) {
this.getTransactions(this.props);
}
this.getTransactions(this.props);
}
componentWillReceiveProps (newProps) {

View File

@@ -128,7 +128,7 @@ class Connection extends Component {
const { api } = this.context;
const { token } = this.state;
api.updateToken(token);
api.updateToken(token, 0);
this.setState({ token: '', validToken: false });
}
}

View File

@@ -32,7 +32,7 @@ export default class Summary extends Component {
}
render () {
const { dappsPort } = this.context.api;
const { dappsUrl } = this.context.api;
const { app } = this.props;
if (!app) {
@@ -41,9 +41,9 @@ export default class Summary extends Component {
let image = <div className={ styles.image }>&nbsp;</div>;
if (app.type === 'local') {
image = <img src={ `http://127.0.0.1:${dappsPort}/${app.id}/${app.iconUrl}` } className={ styles.image } />;
image = <img src={ `${dappsUrl}/${app.id}/${app.iconUrl}` } className={ styles.image } />;
} else {
image = <img src={ `http://127.0.0.1:${dappsPort}${app.image}` } className={ styles.image } />;
image = <img src={ `${dappsUrl}${app.image}` } className={ styles.image } />;
}
return (

View File

@@ -0,0 +1,43 @@
[
{
"id": "0xf9f2d620c2e08f83e45555247146c62185e4ab7cf82a4b9002a265a0d020348f",
"url": "basiccoin",
"name": "Token Deployment",
"description": "Deploy new basic tokens that you are able to send around",
"author": "Parity Team <admin@ethcore.io>",
"version": "1.0.0"
},
{
"id": "0xd1adaede68d344519025e2ff574650cd99d3830fe6d274c7a7843cdc00e17938",
"url": "registry",
"name": "Registry",
"description": "A global registry of addresses on the network",
"author": "Parity Team <admin@ethcore.io>",
"version": "1.0.0"
},
{
"id": "0x0a8048117e51e964628d0f2d26342b3cd915248b59bcce2721e1d05f5cfa2208",
"url": "tokenreg",
"name": "Token Registry",
"description": "A registry of transactable tokens on the network",
"author": "Parity Team <admin@ethcore.io>",
"version": "1.0.0"
},
{
"id": "0xf49089046f53f5d2e5f3513c1c32f5ff57d986e46309a42d2b249070e4e72c46",
"url": "signaturereg",
"name": "Method Registry",
"description": "A registry of method signatures for lookups on transactions",
"author": "Parity Team <admin@ethcore.io>",
"version": "1.0.0"
},
{
"id": "0x058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75",
"url": "githubhint",
"name": "GitHub Hint",
"description": "A mapping of GitHub URLs to hashes for use in contracts as references",
"author": "Parity Team <admin@ethcore.io>",
"version": "1.0.0",
"secure": true
}
]

View File

@@ -14,69 +14,39 @@
// 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, computed, observable } from 'mobx';
import { action, computed, observable, transaction } from 'mobx';
import Contracts from '../../contracts';
import { hashToImageUrl } from '../../redux/util';
const builtinApps = [
{
id: '0xf9f2d620c2e08f83e45555247146c62185e4ab7cf82a4b9002a265a0d020348f',
url: 'basiccoin',
name: 'Token Deployment',
description: 'Deploy new basic tokens that you are able to send around',
author: 'Parity Team <admin@ethcore.io>',
version: '1.0.0'
},
{
id: '0xd1adaede68d344519025e2ff574650cd99d3830fe6d274c7a7843cdc00e17938',
url: 'registry',
name: 'Registry',
description: 'A global registry of addresses on the network',
author: 'Parity Team <admin@ethcore.io>',
version: '1.0.0'
},
{
id: '0x0a8048117e51e964628d0f2d26342b3cd915248b59bcce2721e1d05f5cfa2208',
url: 'tokenreg',
name: 'Token Registry',
description: 'A registry of transactable tokens on the network',
author: 'Parity Team <admin@ethcore.io>',
version: '1.0.0'
},
{
id: '0xf49089046f53f5d2e5f3513c1c32f5ff57d986e46309a42d2b249070e4e72c46',
url: 'signaturereg',
name: 'Method Registry',
description: 'A registry of method signatures for lookups on transactions',
author: 'Parity Team <admin@ethcore.io>',
version: '1.0.0'
},
{
id: '0x058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75',
url: 'githubhint',
name: 'GitHub Hint',
description: 'A mapping of GitHub URLs to hashes for use in contracts as references',
author: 'Parity Team <admin@ethcore.io>',
version: '1.0.0',
secure: true
}
];
import builtinApps from './builtin.json';
const LS_KEY_HIDDEN = 'hiddenApps';
const LS_KEY_EXTERNAL = 'externalApps';
export default class DappsStore {
@observable apps = [];
@observable hidden = [];
@observable externalApps = [];
@observable hiddenApps = [];
@observable modalOpen = false;
constructor (api) {
this._api = api;
this._readHiddenApps();
this._fetch();
this._readExternalApps();
this._fetchBuiltinApps();
this._fetchLocalApps();
this._fetchRegistryApps();
}
@computed get visible () {
return this.apps.filter((app) => !this.hidden.includes(app.id));
return this.apps
.filter((app) => {
return this.externalApps.includes(app.id) || !this.hiddenApps.includes(app.id);
})
.sort((a, b) => a.name.localeCompare(b.name));
}
@action openModal = () => {
@@ -88,12 +58,12 @@ export default class DappsStore {
}
@action hideApp = (id) => {
this.hidden = this.hidden.concat(id);
this.hiddenApps = this.hiddenApps.concat(id);
this._writeHiddenApps();
}
@action showApp = (id) => {
this.hidden = this.hidden.filter((_id) => _id !== id);
this.hiddenApps = this.hiddenApps.filter((_id) => _id !== id);
this._writeHiddenApps();
}
@@ -103,25 +73,48 @@ export default class DappsStore {
: '';
}
_fetch () {
Promise
.all([
this._fetchLocal(),
this._fetchRegistry()
])
.then(([localApps, registryApps]) => {
this.apps = []
.concat(localApps)
.concat(registryApps)
.filter((app) => app.id)
.sort((a, b) => (a.name || '').localeCompare(b.name || ''));
})
.catch((error) => {
console.warn('DappStore:fetch', error);
_fetchBuiltinApps () {
const { dappReg } = Contracts.get();
return Promise
.all(builtinApps.map((app) => dappReg.getImage(app.id)))
.then((imageIds) => {
transaction(() => {
builtinApps.forEach((app, index) => {
app.type = 'builtin';
app.image = hashToImageUrl(imageIds[index]);
this.apps.push(app);
});
});
});
}
_fetchRegistry () {
_fetchLocalApps () {
return fetch(`${this._getHost()}/api/apps`)
.then((response) => {
return response.ok
? response.json()
: [];
})
.then((apps) => {
return apps
.map((app) => {
app.type = 'local';
return app;
})
.filter((app) => app.id && !['ui'].includes(app.id));
})
.then((apps) => {
transaction(() => {
(apps || []).forEach((app) => this.apps.push(app));
});
})
.catch((error) => {
console.warn('DappsStore:fetchLocal', error);
});
}
_fetchRegistryApps () {
const { dappReg } = Contracts.get();
return dappReg
@@ -137,9 +130,9 @@ export default class DappsStore {
return Promise.all(promises);
})
.then((appsInfo) => {
const appIds = appsInfo.map(([appId, owner]) => {
return this._api.util.bytesToHex(appId);
});
const appIds = appsInfo
.map(([appId, owner]) => this._api.util.bytesToHex(appId))
.filter((appId) => !builtinApps.find((app) => app.id === appId));
return Promise
.all([
@@ -149,27 +142,21 @@ export default class DappsStore {
])
.then(([imageIds, contentIds, manifestIds]) => {
return appIds.map((appId, index) => {
const app = builtinApps.find((ba) => ba.id === appId) || {
const app = {
id: appId,
image: hashToImageUrl(imageIds[index]),
contentHash: this._api.util.bytesToHex(contentIds[index]).substr(2),
manifestHash: this._api.util.bytesToHex(manifestIds[index]).substr(2),
type: 'network'
};
app.image = hashToImageUrl(imageIds[index]);
app.type = app.type || 'builtin';
return app;
});
});
})
.then((apps) => {
return Promise
.all(apps.map((app) => {
return app.manifestHash
? this._fetchManifest(app.manifestHash)
: null;
}))
.all(apps.map((app) => this._fetchManifest(app.manifestHash)))
.then((manifests) => {
return apps.map((app, index) => {
const manifest = manifests[index];
@@ -177,7 +164,7 @@ export default class DappsStore {
if (manifest) {
app.manifestHash = null;
Object.keys(manifest)
.filter((key) => key !== 'id')
.filter((key) => ['author', 'description', 'name', 'version'].includes(key))
.forEach((key) => {
app[key] = manifest[key];
});
@@ -192,66 +179,66 @@ export default class DappsStore {
});
});
})
.then((apps) => {
transaction(() => {
(apps || []).forEach((app) => this.apps.push(app));
});
})
.catch((error) => {
console.warn('DappsStore:fetchRegistry', error);
});
}
_fetchManifest (manifestHash, count = 0) {
return fetch(`${this._getHost()}/api/content/${manifestHash}/`)
.then((response) => {
if (response.ok) {
return response.json();
}
if (count < 1) {
return this._fetchManifest(manifestHash, count + 1);
}
return null;
})
.catch(() => {
if (count < 1) {
return this._fetchManifest(manifestHash, count + 1);
}
return null;
});
}
_fetchLocal () {
return fetch(`${this._getHost()}/api/apps`)
_fetchManifest (manifestHash) {
return fetch(`${this._getHost()}/api/content/${manifestHash}/`, { redirect: 'follow', mode: 'cors' })
.then((response) => {
return response.ok
? response.json()
: [];
})
.then((localApps) => {
return localApps
.filter((app) => app && app.id && !['ui'].includes(app.id))
.map((app) => {
app.type = 'local';
return app;
});
: null;
})
.catch((error) => {
console.warn('DappsStore:fetchLocal', error);
console.warn('DappsStore:fetchManifest', error);
return null;
});
}
_readHiddenApps () {
const stored = localStorage.getItem('hiddenApps');
const stored = localStorage.getItem(LS_KEY_HIDDEN);
if (stored) {
try {
this.hidden = JSON.parse(stored);
this.hiddenApps = JSON.parse(stored);
} catch (error) {
console.warn('DappsStore:readHiddenApps', error);
}
}
}
_readExternalApps () {
const stored = localStorage.getItem(LS_KEY_EXTERNAL);
if (stored) {
try {
this.externalApps = JSON.parse(stored);
} catch (error) {
console.warn('DappsStore:readExternalApps', error);
}
}
}
_writeExternalApps () {
try {
localStorage.setItem(LS_KEY_EXTERNAL, JSON.stringify(this.externalApps));
} catch (error) {
console.error('DappsStore:writeExternalApps', error);
}
}
_writeHiddenApps () {
localStorage.setItem('hiddenApps', JSON.stringify(this.hidden));
try {
localStorage.setItem(LS_KEY_HIDDEN, JSON.stringify(this.hiddenApps));
} catch (error) {
console.error('DappsStore:writeHiddenApps', error);
}
}
}

View File

@@ -58,7 +58,7 @@ const defaultViews = {
label: 'Contracts',
route: '/contracts',
value: 'contract',
description: 'Watch and interact with specific contracts that have been deployed on the network. This is a more technically-focussed environment, specifically for advanced users that understand the inner working of certain contracts.'
description: 'Watch and interact with specific contracts that have been deployed on the network. This is a more technically-focused environment, specifically for advanced users that understand the inner working of certain contracts.'
},
status: {
@@ -77,7 +77,7 @@ const defaultViews = {
label: 'Signer',
route: '/signer',
value: 'signer',
description: 'The security focussed area of the application where you can approve any outgoing transactions made from the application as well as those placed into the queue by distributed applications.'
description: 'The secure transaction management area of the application where you can approve any outgoing transactions made from the application as well as those placed into the queue by distributed applications.'
},
settings: {

View File

@@ -198,7 +198,8 @@ module.exports = {
proxy: {
'/api/*': {
target: 'http://127.0.0.1:8080',
changeOrigin: true
changeOrigin: true,
autoRewrite: true
},
'/app/*': {
target: 'http://127.0.0.1:8080',

View File

@@ -85,6 +85,10 @@ pub struct EthashParams {
/// See main EthashParams docs.
#[serde(rename="eip161dTransition")]
pub eip161d_transition: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="maxCodeSize")]
pub max_code_size: Option<Uint>,
}
/// Ethash engine deserialization.

View File

@@ -578,7 +578,7 @@
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>VERSION</key>
<string>1.4.1</string>
<string>1.4.3</string>
</dict>
<key>UUID</key>
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>

View File

@@ -31,7 +31,7 @@ echo -n '{"fat_db":false,"mode":"passive","mode.alarm":3600,"mode.timeout":300,"
chown -R $USER $HOME/.parity $HOME/Library/LaunchAgents $HOME/Library/LaunchAgents/io.parity.ethereum.plist
su $USER -c "launchctl load $HOME/Library/LaunchAgents/io.parity.ethereum.plist"
sleep 1
sleep 5
open http://127.0.0.1:8080/
su $USER -c "open http://127.0.0.1:8080/"

View File

@@ -10,9 +10,9 @@
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
!define VERSIONMAJOR 1
!define VERSIONMINOR 4
!define VERSIONBUILD 1
!define VERSIONBUILD 3
!define ARGS "--warp"
!define FIRST_START_ARGS "--warp --mode=passive"
!define FIRST_START_ARGS "ui --warp --mode=passive"
!addplugindir .\
@@ -160,6 +160,9 @@ section "uninstall"
!insertmacro TerminateApp
# Remove Start Menu launcher
delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk"
delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME} Ethereum.lnk"
delete "$DESKTOP\${APPNAME} Ethereum.lnk"
# Try to remove the Start Menu folder - this will only happen if it is empty
rmDir "$SMPROGRAMS\${COMPANYNAME}"

View File

@@ -95,7 +95,7 @@ impl Configuration {
let wal = !self.args.flag_fast_and_loose;
let warp_sync = self.args.flag_warp;
let geth_compatibility = self.args.flag_geth;
let ui_port = self.ui_port();
let ui_address = self.ui_port().map(|port| (self.ui_interface(), port));
let dapps_conf = self.dapps_config();
let signer_conf = self.signer_config();
let format = try!(self.format());
@@ -243,7 +243,7 @@ impl Configuration {
vm_type: vm_type,
warp_sync: warp_sync,
geth_compatibility: geth_compatibility,
ui_port: ui_port,
ui_address: ui_address,
net_settings: self.network_settings(),
dapps_conf: dapps_conf,
signer_conf: signer_conf,
@@ -859,7 +859,7 @@ mod tests {
wal: true,
vm_type: Default::default(),
geth_compatibility: false,
ui_port: Some(8180),
ui_address: Some(("127.0.0.1".into(), 8180)),
net_settings: Default::default(),
dapps_conf: Default::default(),
signer_conf: Default::default(),

View File

@@ -58,7 +58,7 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<We
return Ok(None);
}
let signer_port = deps.apis.signer_service.port();
let signer_address = deps.apis.signer_service.address();
let url = format!("{}:{}", configuration.interface, configuration.port);
let addr = try!(url.parse().map_err(|_| format!("Invalid Webapps listen host/port given: {}", url)));
@@ -73,7 +73,7 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result<Option<We
(username.to_owned(), password)
});
Ok(Some(try!(setup_dapps_server(deps, configuration.dapps_path, &addr, configuration.hosts, auth, signer_port))))
Ok(Some(try!(setup_dapps_server(deps, configuration.dapps_path, &addr, configuration.hosts, auth, signer_address))))
}
pub use self::server::WebappServer;
@@ -91,7 +91,7 @@ mod server {
_url: &SocketAddr,
_allowed_hosts: Option<Vec<String>>,
_auth: Option<(String, String)>,
_signer_port: Option<u16>,
_signer_address: Option<(String, u16)>,
) -> Result<WebappServer, String> {
Err("Your Parity version has been compiled without WebApps support.".into())
}
@@ -120,7 +120,7 @@ mod server {
url: &SocketAddr,
allowed_hosts: Option<Vec<String>>,
auth: Option<(String, String)>,
signer_port: Option<u16>,
signer_address: Option<(String, u16)>,
) -> Result<WebappServer, String> {
use ethcore_dapps as dapps;
@@ -131,7 +131,7 @@ mod server {
let sync = deps.sync.clone();
let client = deps.client.clone();
server.with_sync_status(Arc::new(move || is_major_importing(Some(sync.status().state), client.queue_info())));
server.with_signer_port(signer_port);
server.with_signer_address(signer_address);
let server = rpc_apis::setup_rpc(server, deps.apis.clone(), rpc_apis::ApiSet::UnsafeContext);
let start_result = match auth {

View File

@@ -15,9 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::{io, env};
use std::io::{Write, Read, BufReader, BufRead};
use std::io::{Write, BufReader, BufRead};
use std::time::Duration;
use std::path::Path;
use std::fs::File;
use util::{clean_0x, U256, Uint, Address, path, CompactionProfile};
use util::journaldb::Algorithm;
@@ -299,13 +298,11 @@ pub fn password_prompt() -> Result<String, String> {
}
/// Read a password from password file.
pub fn password_from_file<P>(path: P) -> Result<String, String> where P: AsRef<Path> {
let mut file = try!(File::open(path).map_err(|_| "Unable to open password file."));
let mut file_content = String::new();
match file.read_to_string(&mut file_content) {
Ok(_) => Ok(file_content.trim().into()),
Err(_) => Err("Unable to read password file.".into()),
}
pub fn password_from_file(path: String) -> Result<String, String> {
let passwords = try!(passwords_from_files(vec![path]));
// use only first password from the file
passwords.get(0).map(String::to_owned)
.ok_or_else(|| "Password file seems to be empty.".to_owned())
}
/// Reads passwords from files. Treats each line as a separate password.
@@ -314,10 +311,11 @@ pub fn passwords_from_files(files: Vec<String>) -> Result<Vec<String>, String> {
let file = try!(File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)));
let reader = BufReader::new(&file);
let lines = reader.lines()
.map(|l| l.unwrap())
.filter_map(|l| l.ok())
.map(|pwd| pwd.trim().to_owned())
.collect::<Vec<String>>();
Ok(lines)
}).collect::<Result<Vec<Vec<String>>, String>>();
}).collect::<Result<Vec<Vec<String>>, String>>();
Ok(try!(passwords).into_iter().flat_map(|x| x).collect())
}
@@ -418,7 +416,20 @@ mod tests {
let path = RandomTempPath::new();
let mut file = File::create(path.as_path()).unwrap();
file.write_all(b"a bc ").unwrap();
assert_eq!(password_from_file(path).unwrap().as_bytes(), b"a bc");
assert_eq!(password_from_file(path.as_str().into()).unwrap().as_bytes(), b"a bc");
}
#[test]
fn test_password_multiline() {
let path = RandomTempPath::new();
let mut file = File::create(path.as_path()).unwrap();
file.write_all(br#" password with trailing whitespace
those passwords should be
ignored
but the first password is trimmed
"#).unwrap();
assert_eq!(&password_from_file(path.as_str().into()).unwrap(), "password with trailing whitespace");
}
#[test]

View File

@@ -37,7 +37,7 @@ pub enum Api {
Net,
/// Eth (Safe)
Eth,
/// Geth-compatible "personal" API (DEPRECATED; only used in `--geth` mode.)
/// Geth-compatible "personal" API (DEPRECATED; only used in `--geth` mode.)
Personal,
/// Signer - Confirm transactions in Signer (UNSAFE: Passwords, List of transactions)
Signer,
@@ -119,6 +119,7 @@ pub struct Dependencies {
pub settings: Arc<NetworkSettings>,
pub net_service: Arc<ManageNetwork>,
pub geth_compatibility: bool,
pub dapps_interface: Option<String>,
pub dapps_port: Option<u16>,
}
@@ -228,6 +229,7 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
deps.logger.clone(),
deps.settings.clone(),
signer,
deps.dapps_interface.clone(),
deps.dapps_port,
).to_delegate());

View File

@@ -82,7 +82,7 @@ pub struct RunCmd {
pub wal: bool,
pub vm_type: VMType,
pub geth_compatibility: bool,
pub ui_port: Option<u16>,
pub ui_address: Option<(String, u16)>,
pub net_settings: NetworkSettings,
pub dapps_conf: dapps::Configuration,
pub signer_conf: signer::Configuration,
@@ -262,7 +262,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies {
signer_service: Arc::new(rpc_apis::SignerService::new(move || {
signer::generate_new_token(signer_path.clone()).map_err(|e| format!("{:?}", e))
}, cmd.ui_port)),
}, cmd.ui_address)),
snapshot: snapshot_service.clone(),
client: client.clone(),
sync: sync_provider.clone(),
@@ -274,6 +274,10 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
settings: Arc::new(cmd.net_settings.clone()),
net_service: manage_network.clone(),
geth_compatibility: cmd.geth_compatibility,
dapps_interface: match cmd.dapps_conf.enabled {
true => Some(cmd.dapps_conf.interface.clone()),
false => None,
},
dapps_port: match cmd.dapps_conf.enabled {
true => Some(cmd.dapps_conf.port),
false => None,

View File

@@ -22,18 +22,18 @@ use v1::helpers::signing_queue::{ConfirmationsQueue};
pub struct SignerService {
queue: Arc<ConfirmationsQueue>,
generate_new_token: Box<Fn() -> Result<String, String> + Send + Sync + 'static>,
port: Option<u16>,
address: Option<(String, u16)>,
}
impl SignerService {
/// Creates new Signer Service given function to generate new tokens.
pub fn new<F>(new_token: F, port: Option<u16>) -> Self
pub fn new<F>(new_token: F, address: Option<(String, u16)>) -> Self
where F: Fn() -> Result<String, String> + Send + Sync + 'static {
SignerService {
queue: Arc::new(ConfirmationsQueue::default()),
generate_new_token: Box::new(new_token),
port: port,
address: address,
}
}
@@ -47,20 +47,20 @@ impl SignerService {
self.queue.clone()
}
/// Returns signer port (if signer enabled) or `None` otherwise
pub fn port(&self) -> Option<u16> {
self.port
/// Returns signer address (if signer enabled) or `None` otherwise
pub fn address(&self) -> Option<(String, u16)> {
self.address.clone()
}
/// Returns true if Signer is enabled.
pub fn is_enabled(&self) -> bool {
self.port.is_some()
self.address.is_some()
}
#[cfg(test)]
/// Creates new Signer Service for tests.
pub fn new_test(port: Option<u16>) -> Self {
SignerService::new(|| Ok("new_token".into()), port)
pub fn new_test(address: Option<(String, u16)>) -> Self {
SignerService::new(|| Ok("new_token".into()), address)
}
}

View File

@@ -52,6 +52,7 @@ pub struct ParityClient<C, M, S: ?Sized> where
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
signer: Option<Arc<SignerService>>,
dapps_interface: Option<String>,
dapps_port: Option<u16>,
}
@@ -70,6 +71,7 @@ impl<C, M, S: ?Sized> ParityClient<C, M, S> where
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
signer: Option<Arc<SignerService>>,
dapps_interface: Option<String>,
dapps_port: Option<u16>,
) -> Self {
ParityClient {
@@ -81,6 +83,7 @@ impl<C, M, S: ?Sized> ParityClient<C, M, S> where
logger: logger,
settings: settings,
signer: signer,
dapps_interface: dapps_interface,
dapps_port: dapps_port,
}
}
@@ -261,7 +264,8 @@ impl<C, M, S: ?Sized> Parity for ParityClient<C, M, S> where
self.signer
.clone()
.and_then(|signer| signer.port())
.and_then(|signer| signer.address())
.map(|address| address.1)
.ok_or_else(|| errors::signer_disabled())
}
@@ -272,6 +276,13 @@ impl<C, M, S: ?Sized> Parity for ParityClient<C, M, S> where
.ok_or_else(|| errors::dapps_disabled())
}
fn dapps_interface(&self) -> Result<String, Error> {
try!(self.active());
self.dapps_interface.clone()
.ok_or_else(|| errors::dapps_disabled())
}
fn next_nonce(&self, address: H160) -> Result<U256, Error> {
try!(self.active());
let address: Address = address.into();

View File

@@ -209,6 +209,8 @@ impl MinerService for TestMinerService {
gas_used: r.gas_used.clone(),
contract_address: None,
logs: r.logs.clone(),
log_bloom: r.log_bloom,
state_root: r.state_root,
}
)
}

View File

@@ -485,7 +485,7 @@ fn rpc_eth_pending_transaction_by_hash() {
tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
}
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"value":"0xa"},"id":1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":0,"value":"0xa"},"id":1}"#;
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_getTransactionByHash",
@@ -879,7 +879,9 @@ fn rpc_eth_transaction_receipt() {
transaction_hash: H256::new(),
transaction_index: 0,
log_index: 1,
}]
}],
log_bloom: 0.into(),
state_root: 0.into(),
};
let hash = H256::from_str("b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").unwrap();
@@ -892,7 +894,7 @@ fn rpc_eth_transaction_receipt() {
"params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
"id": 1
}"#;
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#;
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#;
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
}

View File

@@ -38,6 +38,7 @@ pub struct Dependencies {
pub settings: Arc<NetworkSettings>,
pub network: Arc<ManageNetwork>,
pub accounts: Arc<AccountProvider>,
pub dapps_interface: Option<String>,
pub dapps_port: Option<u16>,
}
@@ -61,6 +62,7 @@ impl Dependencies {
}),
network: Arc::new(TestManageNetwork),
accounts: Arc::new(AccountProvider::transient_provider()),
dapps_interface: Some("127.0.0.1".into()),
dapps_port: Some(18080),
}
}
@@ -75,6 +77,7 @@ impl Dependencies {
self.logger.clone(),
self.settings.clone(),
signer,
self.dapps_interface.clone(),
self.dapps_port,
)
}
@@ -238,7 +241,7 @@ fn rpc_parity_node_name() {
#[test]
fn rpc_parity_unsigned_transactions_count() {
let deps = Dependencies::new();
let io = deps.with_signer(SignerService::new_test(Some(18180)));
let io = deps.with_signer(SignerService::new_test(Some(("127.0.0.1".into(), 18180))));
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":0,"id":1}"#;
@@ -282,7 +285,7 @@ fn rpc_parity_encrypt() {
fn rpc_parity_signer_port() {
// given
let deps = Dependencies::new();
let io1 = deps.with_signer(SignerService::new_test(Some(18180)));
let io1 = deps.with_signer(SignerService::new_test(Some(("127.0.0.1".into(), 18180))));
let io2 = deps.default_client();
// when
@@ -313,6 +316,24 @@ fn rpc_parity_dapps_port() {
assert_eq!(io2.handle_request_sync(request), Some(response2.to_owned()));
}
#[test]
fn rpc_parity_dapps_interface() {
// given
let mut deps = Dependencies::new();
let io1 = deps.default_client();
deps.dapps_interface = None;
let io2 = deps.default_client();
// when
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsInterface", "params": [], "id": 1}"#;
let response1 = r#"{"jsonrpc":"2.0","result":"127.0.0.1","id":1}"#;
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
// then
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
assert_eq!(io2.handle_request_sync(request), Some(response2.to_owned()));
}
#[test]
fn rpc_parity_next_nonce() {
let deps = Dependencies::new();

View File

@@ -123,6 +123,10 @@ build_rpc_trait! {
#[rpc(name = "parity_dappsPort")]
fn dapps_port(&self) -> Result<u16, Error>;
/// Returns current Dapps Server interface address or an error if dapps server is disabled.
#[rpc(name = "parity_dappsInterface")]
fn dapps_interface(&self) -> Result<String, Error>;
/// Returns next nonce for particular sender. Should include all transactions in the queue.
#[rpc(name = "parity_nextNonce")]
fn next_nonce(&self, H160) -> Result<U256, Error>;

View File

@@ -139,7 +139,7 @@ mod tests {
fn test_serialize_block_transactions() {
let t = BlockTransactions::Full(vec![Transaction::default()]);
let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null}]"#);
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"v":0,"r":"0x0000000000000000000000000000000000000000000000000000000000000000","s":"0x0000000000000000000000000000000000000000000000000000000000000000"}]"#);
let t = BlockTransactions::Hashes(vec![H256::default().into()]);
let serialized = serde_json::to_string(&t).unwrap();

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use v1::types::{Log, H160, H256, U256};
use v1::types::{Log, H160, H256, H2048, U256};
use ethcore::receipt::{Receipt as EthReceipt, RichReceipt, LocalizedReceipt};
/// Receipt
@@ -43,6 +43,12 @@ pub struct Receipt {
pub contract_address: Option<H160>,
/// Logs
pub logs: Vec<Log>,
/// State Root
#[serde(rename="root")]
pub state_root: H256,
/// Logs bloom
#[serde(rename="logsBloom")]
pub logs_bloom: H2048,
}
impl From<LocalizedReceipt> for Receipt {
@@ -56,6 +62,8 @@ impl From<LocalizedReceipt> for Receipt {
gas_used: Some(r.gas_used.into()),
contract_address: r.contract_address.map(Into::into),
logs: r.logs.into_iter().map(Into::into).collect(),
state_root: r.state_root.into(),
logs_bloom: r.log_bloom.into(),
}
}
}
@@ -71,6 +79,8 @@ impl From<RichReceipt> for Receipt {
gas_used: Some(r.gas_used.into()),
contract_address: r.contract_address.map(Into::into),
logs: r.logs.into_iter().map(Into::into).collect(),
state_root: r.state_root.into(),
logs_bloom: r.log_bloom.into(),
}
}
}
@@ -86,6 +96,8 @@ impl From<EthReceipt> for Receipt {
gas_used: None,
contract_address: None,
logs: r.logs.into_iter().map(Into::into).collect(),
state_root: r.state_root.into(),
logs_bloom: r.log_bloom.into(),
}
}
}
@@ -93,35 +105,36 @@ impl From<EthReceipt> for Receipt {
#[cfg(test)]
mod tests {
use serde_json;
use std::str::FromStr;
use v1::types::{Log, Receipt, U256, H256, H160};
use v1::types::{Log, Receipt};
#[test]
fn receipt_serialization() {
let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","type":"mined"}]}"#;
let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","type":"mined"}],"root":"0x000000000000000000000000000000000000000000000000000000000000000a","logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f"}"#;
let receipt = Receipt {
transaction_hash: Some(H256::from(0)),
transaction_index: Some(U256::from(0)),
block_hash: Some(H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap()),
block_number: Some(U256::from(0x4510c)),
cumulative_gas_used: U256::from(0x20),
gas_used: Some(U256::from(0x10)),
transaction_hash: Some(0.into()),
transaction_index: Some(0.into()),
block_hash: Some("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5".parse().unwrap()),
block_number: Some(0x4510c.into()),
cumulative_gas_used: 0x20.into(),
gas_used: Some(0x10.into()),
contract_address: None,
logs: vec![Log {
address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
address: "33990122638b9132ca29c723bdf037f1a891a70c".parse().unwrap(),
topics: vec![
H256::from_str("a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc").unwrap(),
H256::from_str("4861736852656700000000000000000000000000000000000000000000000000").unwrap(),
"a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc".parse().unwrap(),
"4861736852656700000000000000000000000000000000000000000000000000".parse().unwrap(),
],
data: vec![].into(),
block_hash: Some(H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap()),
block_number: Some(U256::from(0x4510c)),
transaction_hash: Some(H256::default()),
transaction_index: Some(U256::default()),
log_index: Some(U256::from(1)),
log_type: "mined".to_owned(),
}]
block_hash: Some("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5".parse().unwrap()),
block_number: Some(0x4510c.into()),
transaction_hash: Some(0.into()),
transaction_index: Some(0.into()),
log_index: Some(1.into()),
log_type: "mined".into(),
}],
logs_bloom: 15.into(),
state_root: 10.into(),
};
let serialized = serde_json::to_string(&receipt).unwrap();

View File

@@ -54,10 +54,17 @@ pub struct Transaction {
/// Public key of the signer.
#[serde(rename="publicKey")]
pub public_key: Option<H512>,
/// The V field of the signature.
pub v: u8,
/// The R field of the signature.
pub r: H256,
/// The S field of the signature.
pub s: H256,
}
impl From<LocalizedTransaction> for Transaction {
fn from(t: LocalizedTransaction) -> Transaction {
let signature = t.signature();
Transaction {
hash: t.hash().into(),
nonce: t.nonce.into(),
@@ -79,12 +86,16 @@ impl From<LocalizedTransaction> for Transaction {
},
raw: ::rlp::encode(&t.signed).to_vec().into(),
public_key: t.public_key().ok().map(Into::into),
v: signature.v(),
r: signature.r().into(),
s: signature.s().into(),
}
}
}
impl From<SignedTransaction> for Transaction {
fn from(t: SignedTransaction) -> Transaction {
let signature = t.signature();
Transaction {
hash: t.hash().into(),
nonce: t.nonce.into(),
@@ -106,6 +117,9 @@ impl From<SignedTransaction> for Transaction {
},
raw: ::rlp::encode(&t).to_vec().into(),
public_key: t.public_key().ok().map(Into::into),
v: signature.v(),
r: signature.r().into(),
s: signature.s().into(),
}
}
}
@@ -119,7 +133,7 @@ mod tests {
fn test_transaction_serialize() {
let t = Transaction::default();
let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null}"#);
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"v":0,"r":"0x0000000000000000000000000000000000000000000000000000000000000000","s":"0x0000000000000000000000000000000000000000000000000000000000000000"}"#);
}
}

View File

@@ -16,7 +16,7 @@
use std::ops::{Deref, DerefMut};
use std::thread;
use std::time::{self, Duration};
use std::time;
use std::sync::Arc;
use devtools::{http_client, RandomTempPath};
use rpc::ConfirmationsQueue;
@@ -50,7 +50,6 @@ pub fn serve() -> (Server, usize, GuardedAuthCodes) {
let builder = ServerBuilder::new(queue, path.to_path_buf());
let port = 35000 + rand::random::<usize>() % 10000;
let res = builder.start(format!("127.0.0.1:{}", port).parse().unwrap()).unwrap();
thread::sleep(Duration::from_millis(25));
(res, port, GuardedAuthCodes {
authcodes: AuthCodes::from_file(&path).unwrap(),

View File

@@ -457,12 +457,19 @@ impl ChainSync {
if self.state != SyncState::WaitingPeers {
return;
}
let best_block = io.chain().chain_info().best_block_number;
// Make sure the snapshot block is not too far away from best block and network best block and
// that it is higher than fork detection block
let our_best_block = io.chain().chain_info().best_block_number;
let fork_block = self.fork_block.as_ref().map(|&(n, _)| n).unwrap_or(0);
let (best_hash, max_peers, snapshot_peers) = {
//collect snapshot infos from peers
let snapshots = self.peers.iter()
.filter(|&(_, p)| p.is_allowed() && p.snapshot_number.map_or(false, |sn| best_block < sn && (sn - best_block) > SNAPSHOT_RESTORE_THRESHOLD))
.filter(|&(_, p)| p.is_allowed() && p.snapshot_number.map_or(false, |sn|
our_best_block < sn && (sn - our_best_block) > SNAPSHOT_RESTORE_THRESHOLD &&
sn > fork_block &&
self.highest_block.map_or(true, |highest| highest >= sn && (highest - sn) <= SNAPSHOT_RESTORE_THRESHOLD)
))
.filter_map(|(p, peer)| peer.snapshot_hash.map(|hash| (p, hash.clone())));
let mut snapshot_peers = HashMap::new();

View File

@@ -3,7 +3,7 @@ description = "Ethcore utility library"
homepage = "http://ethcore.io"
license = "GPL-3.0"
name = "ethcore-util"
version = "1.4.1"
version = "1.4.3"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"

View File

@@ -4,7 +4,7 @@ homepage = "http://ethcore.io"
repository = "https://github.com/ethcore/parity"
license = "GPL-3.0"
name = "ethcore-bigint"
version = "0.1.1"
version = "0.1.2"
authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs"

View File

@@ -386,6 +386,12 @@ macro_rules! impl_hash {
}
}
}
impl<'a> From<&'a [u8]> for $from {
fn from(s: &'a [u8]) -> $from {
$from::from_slice(s)
}
}
}
}

View File

@@ -17,10 +17,10 @@
//! Database of byte-slices keyed to their Keccak hash.
use hash::*;
use std::collections::HashMap;
use elastic_array::ElasticArray256;
use elastic_array::ElasticArray128;
/// `HashDB` value type.
pub type DBValue = ElasticArray256<u8>;
pub type DBValue = ElasticArray128<u8>;
/// Trait modelling datastore keyed by a 32-byte Keccak hash.
pub trait HashDB: AsHashDB + Send + Sync {

View File

@@ -464,6 +464,7 @@ impl Database {
try!(db.write_opt(batch, &self.write_opts));
for column in self.flushing.write().iter_mut() {
column.clear();
column.shrink_to_fit();
}
Ok(())
},

View File

@@ -41,6 +41,7 @@ DWORD parityProcId = 0;
NOTIFYICONDATA nidApp;
WCHAR szTitle[MAX_LOADSTRING];
WCHAR szWindowClass[MAX_LOADSTRING];
LPCWCHAR commandLineFiltered = L"";
LPCWSTR cParityExe = _T("parity.exe");
@@ -85,7 +86,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
OpenUI();
return 0;
}
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_PTRAY, szWindowClass, MAX_LOADSTRING);
@@ -133,6 +133,24 @@ ATOM MyRegisterClass(HINSTANCE hInstance)
bool InitInstance(HINSTANCE hInstance, int nCmdShow, LPWSTR cmdLine)
{
if (lstrlen(cmdLine) > 0)
{
int commandLineArgs = 0;
LPWSTR* commandLine = CommandLineToArgvW(cmdLine, &commandLineArgs);
LPWSTR filteredArgs = new WCHAR[lstrlen(cmdLine) + 2];
filteredArgs[0] = '\0';
for (int i = 0; i < commandLineArgs; i++)
{
// Remove "ui" from command line
if (lstrcmp(commandLine[i], L"ui") != 0)
{
lstrcat(filteredArgs, commandLine[i]);
lstrcat(filteredArgs, L" ");
}
}
commandLineFiltered = filteredArgs;
}
// Check if already running
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
@@ -190,7 +208,9 @@ bool InitInstance(HINSTANCE hInstance, int nCmdShow, LPWSTR cmdLine)
nidApp.uCallbackMessage = WM_USER_SHELLICON;
LoadString(hInstance, IDS_CONTROL_PARITY, nidApp.szTip, MAX_LOADSTRING);
Shell_NotifyIcon(NIM_ADD, &nidApp);
return TRUE;
SetTimer(hWnd, 0, 1000, nullptr);
return true;
}
@@ -294,8 +314,10 @@ void OpenUI()
PROCESS_INFORMATION procInfo = { 0 };
STARTUPINFO startupInfo = { sizeof(STARTUPINFO) };
LPWSTR cmd = _T("parity.exe ui");
CreateProcess(path, cmd, nullptr, nullptr, false, CREATE_NO_WINDOW, nullptr, nullptr, &startupInfo, &procInfo);
LPWSTR args = new WCHAR[lstrlen(commandLineFiltered) + MAX_PATH + 2];
lstrcpy(args, L"parity.exe ui ");
lstrcat(args, commandLineFiltered);
CreateProcess(path, args, nullptr, nullptr, false, CREATE_NO_WINDOW, nullptr, nullptr, &startupInfo, &procInfo);
}
bool AutostartEnabled() {
@@ -321,10 +343,14 @@ void EnableAutostart(bool enable) {
if (enable)
{
TCHAR path[MAX_PATH] = { 0 };
if (!GetTrayExePath(path, MAX_PATH))
return;
RegSetValueEx(hKey, L"Parity", 0, REG_SZ, (LPBYTE)path, MAX_PATH);
LPWSTR args = new WCHAR[lstrlen(commandLineFiltered) + MAX_PATH + 2];
if (GetTrayExePath(args, MAX_PATH))
{
lstrcat(args, L" ");
lstrcat(args, commandLineFiltered);
RegSetValueEx(hKey, L"Parity", 0, REG_SZ, (LPBYTE)args, MAX_PATH);
}
delete[] args;
}
else
{