diff --git a/.github/workflows/yarn-lint.yml b/.github/workflows/yarn.yml
similarity index 79%
rename from .github/workflows/yarn-lint.yml
rename to .github/workflows/yarn.yml
index 7d481a4480..50949480b4 100644
--- a/.github/workflows/yarn-lint.yml
+++ b/.github/workflows/yarn.yml
@@ -1,6 +1,6 @@
on: [push, pull_request]
-name: yarn-lint
+name: yarn
jobs:
lint:
@@ -14,3 +14,5 @@ jobs:
run: yarn
- working-directory: ./test
run: yarn lint
+ - working-directory: ./test
+ run: yarn test-mock
diff --git a/Cargo.lock b/Cargo.lock
index b156e752fc..8e640e8f69 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6,6 +6,38 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
+[[package]]
+name = "aes"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54eb1d8fe354e5fc611daf4f2ea97dd45a765f4f1e4512306ec183ae2e8f20c9"
+dependencies = [
+ "aes-soft",
+ "aesni",
+ "block-cipher-trait",
+]
+
+[[package]]
+name = "aes-soft"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d"
+dependencies = [
+ "block-cipher-trait",
+ "byteorder",
+ "opaque-debug",
+]
+
+[[package]]
+name = "aesni"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100"
+dependencies = [
+ "block-cipher-trait",
+ "opaque-debug",
+]
+
[[package]]
name = "aho-corasick"
version = "0.6.4"
@@ -30,7 +62,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -62,7 +94,7 @@ checksum = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
dependencies = [
"libc",
"termion",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -81,7 +113,7 @@ dependencies = [
"cfg-if",
"libc",
"rustc-demangle",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -112,9 +144,9 @@ checksum = "1955ebdd52d5c5f1fb4f94e97aa241c2ce5729d200b3c34fc71ac6ff7a7cc556"
[[package]]
name = "bitflags"
-version = "1.0.3"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bitstring"
@@ -122,6 +154,18 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e54f7b7a46d7b183eb41e2d82965261fa8a1597c68b50aced268ee1fc70272d"
+[[package]]
+name = "blake2"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
+dependencies = [
+ "byte-tools",
+ "crypto-mac",
+ "digest",
+ "opaque-debug",
+]
+
[[package]]
name = "block-buffer"
version = "0.7.3"
@@ -134,6 +178,25 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "block-cipher-trait"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "block-modes"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31aa8410095e39fdb732909fb5730a48d5bd7c2e3cd76bd1b07b3dbea130c529"
+dependencies = [
+ "block-cipher-trait",
+ "block-padding",
+]
+
[[package]]
name = "block-padding"
version = "0.1.4"
@@ -239,6 +302,15 @@ dependencies = [
"bitflags",
]
+[[package]]
+name = "cloudabi"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
+dependencies = [
+ "bitflags",
+]
+
[[package]]
name = "cmake"
version = "0.1.35"
@@ -279,8 +351,9 @@ dependencies = [
"log 0.4.6",
"never-type",
"panic_hook",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
+ "rlp",
"rpassword",
"rustc-serialize",
"serde",
@@ -319,7 +392,7 @@ dependencies = [
"lru-cache",
"merkle-trie",
"num-rational",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"rand 0.6.1",
"rand_xorshift",
@@ -332,19 +405,29 @@ dependencies = [
[[package]]
name = "codechain-crypto"
-version = "0.1.0"
-source = "git+https://github.com/CodeChain-io/rust-codechain-crypto.git#2857470de2f5480b7d61ff57fb652f9d9fc5585b"
+version = "0.2.0"
+source = "git+https://github.com/CodeChain-io/rust-codechain-crypto.git#565c1eebf3abc909ed297bee584dddb84784d838"
dependencies = [
+ "aes",
+ "blake2",
+ "block-modes",
+ "ctr",
+ "digest",
+ "hex",
"primitives",
"quick-error",
"ring",
- "rust-crypto",
+ "ripemd160",
+ "scrypt",
+ "sha-1",
+ "sha2",
+ "sha3",
]
[[package]]
name = "codechain-db"
-version = "0.1.0"
-source = "git+https://github.com/CodeChain-io/rust-codechain-db.git#9948464d24f3432f70fcb12df97c81ec8eab7bfa"
+version = "0.2.0"
+source = "git+https://github.com/CodeChain-io/rust-codechain-db.git#08bd8ceeb360a1e17e011b4dcb084333ddda5cab"
dependencies = [
"codechain-crypto",
"kvdb",
@@ -365,7 +448,7 @@ dependencies = [
"lazy_static 1.2.0",
"log 0.4.6",
"never-type",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"rand 0.6.1",
"rlp",
@@ -380,7 +463,7 @@ dependencies = [
"crossbeam",
"log 0.4.6",
"mio",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
]
[[package]]
@@ -403,7 +486,7 @@ dependencies = [
"codechain-crypto",
"lazy_static 1.2.0",
"never-type",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"rand 0.6.1",
"rand_xorshift",
@@ -427,7 +510,7 @@ dependencies = [
"libc",
"log 0.4.6",
"matches",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"rand 0.6.1",
"rustc-hex 1.0.0",
@@ -448,7 +531,7 @@ dependencies = [
"env_logger 0.6.0",
"lazy_static 1.2.0",
"log 0.4.6",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"sendgrid",
"serde",
"serde_derive",
@@ -473,7 +556,7 @@ dependencies = [
"log 0.4.6",
"mio",
"never-type",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"rand 0.6.1",
"rlp",
@@ -508,7 +591,7 @@ dependencies = [
"kvdb-rocksdb",
"lazy_static 1.2.0",
"log 0.4.6",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"rand 0.6.1",
"rlp",
@@ -536,7 +619,7 @@ dependencies = [
"log 0.4.6",
"lru-cache",
"merkle-trie",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"rlp",
"rlp_derive",
@@ -555,7 +638,7 @@ dependencies = [
"jsonrpc-derive",
"jsonrpc-tcp-server",
"log 0.4.6",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
"primitives",
"tokio-core",
"tokio-io",
@@ -566,6 +649,7 @@ name = "codechain-sync"
version = "0.1.0"
dependencies = [
"codechain-core",
+ "codechain-crypto",
"codechain-db",
"codechain-key",
"codechain-logger",
@@ -578,13 +662,11 @@ dependencies = [
"log 0.4.6",
"merkle-trie",
"never-type",
- "parking_lot 0.6.4",
"primitives",
"rand 0.6.1",
"rlp",
"snap",
"tempfile",
- "time",
"token-generator",
"trie-standardmap",
]
@@ -595,7 +677,7 @@ version = "0.1.0"
dependencies = [
"codechain-logger",
"log 0.4.6",
- "parking_lot 0.6.4",
+ "parking_lot 0.11.0",
]
[[package]]
@@ -741,6 +823,26 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+[[package]]
+name = "crypto-mac"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
+[[package]]
+name = "ctr"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736"
+dependencies = [
+ "block-cipher-trait",
+ "stream-cipher",
+]
+
[[package]]
name = "ctrlc"
version = "1.1.1"
@@ -788,7 +890,7 @@ dependencies = [
"openssl-sys",
"pkg-config",
"vcpkg",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -856,15 +958,6 @@ dependencies = [
"termcolor 1.0.4",
]
-[[package]]
-name = "error-chain"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
-dependencies = [
- "backtrace",
-]
-
[[package]]
name = "ethbloom"
version = "0.5.0"
@@ -986,7 +1079,7 @@ dependencies = [
"lazy_static 1.2.0",
"libc",
"libloading",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1075,17 +1168,6 @@ dependencies = [
"wasi",
]
-[[package]]
-name = "getset"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54c7f36a235738bb25904d6a2b3dbb28f6f5736cd3918c4bf80d6bb236200782"
-dependencies = [
- "proc-macro2 0.3.8",
- "quote 0.5.2",
- "syn 0.13.11",
-]
-
[[package]]
name = "globset"
version = "0.4.1"
@@ -1123,7 +1205,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1135,6 +1217,22 @@ dependencies = [
"libc",
]
+[[package]]
+name = "hex"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
+
+[[package]]
+name = "hmac"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
+dependencies = [
+ "crypto-mac",
+ "digest",
+]
+
[[package]]
name = "http"
version = "0.1.17"
@@ -1248,6 +1346,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
+[[package]]
+name = "instant"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
+
[[package]]
name = "interleaved-ordered"
version = "0.1.1"
@@ -1360,6 +1464,12 @@ dependencies = [
"ws",
]
+[[package]]
+name = "keccak"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
+
[[package]]
name = "kernel32-sys"
version = "0.2.2"
@@ -1433,9 +1543,9 @@ checksum = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0"
[[package]]
name = "libc"
-version = "0.2.62"
+version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
+checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
[[package]]
name = "libflate"
@@ -1455,7 +1565,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
dependencies = [
"cc",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1512,7 +1622,16 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc"
dependencies = [
- "scopeguard 1.0.0",
+ "scopeguard 1.1.0",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
+dependencies = [
+ "scopeguard 1.1.0",
]
[[package]]
@@ -1562,11 +1681,12 @@ checksum = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
[[package]]
name = "merkle-trie"
-version = "0.1.0"
-source = "git+https://github.com/CodeChain-io/rust-merkle-trie.git#a6e067fe71c232d9024952ee63905ab4f5c4407d"
+version = "0.4.0"
+source = "git+https://github.com/CodeChain-io/rust-merkle-trie.git#c2a84172e9c212bee1a29ae2e056d3ea988115ce"
dependencies = [
"codechain-crypto",
"codechain-db",
+ "lru-cache",
"primitives",
"rand 0.6.1",
"rlp",
@@ -1644,7 +1764,7 @@ dependencies = [
"log 0.4.6",
"mio",
"miow 0.3.3",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1677,7 +1797,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226"
dependencies = [
"socket2",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1715,7 +1835,7 @@ checksum = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0"
dependencies = [
"cfg-if",
"libc",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1898,7 +2018,7 @@ dependencies = [
"tokio",
"tokio-named-pipes",
"tokio-uds",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1922,6 +2042,17 @@ dependencies = [
"rustc_version",
]
+[[package]]
+name = "parking_lot"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
+dependencies = [
+ "instant",
+ "lock_api 0.4.1",
+ "parking_lot_core 0.8.0",
+]
+
[[package]]
name = "parking_lot_core"
version = "0.3.1"
@@ -1932,7 +2063,7 @@ dependencies = [
"rand 0.5.5",
"rustc_version",
"smallvec 0.6.4",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -1942,12 +2073,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
dependencies = [
"cfg-if",
- "cloudabi",
+ "cloudabi 0.0.3",
"libc",
"redox_syscall",
"rustc_version",
"smallvec 0.6.4",
- "winapi 0.3.6",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
+dependencies = [
+ "cfg-if",
+ "cloudabi 0.1.0",
+ "instant",
+ "libc",
+ "redox_syscall",
+ "smallvec 1.4.1",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "pbkdf2"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9"
+dependencies = [
+ "byteorder",
+ "crypto-mac",
]
[[package]]
@@ -2025,7 +2181,7 @@ checksum = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
[[package]]
name = "primitives"
version = "0.4.0"
-source = "git+https://github.com/CodeChain-io/rust-codechain-primitives.git#9dbda1bcc2b8f68c00e6426754800fb806e8117a"
+source = "git+https://github.com/CodeChain-io/rust-codechain-primitives.git#eb8da500a77fa84e53750e8661a8603a78a2a7b3"
dependencies = [
"ethereum-types",
]
@@ -2127,7 +2283,7 @@ checksum = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
dependencies = [
"fuchsia-zircon",
"libc",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -2136,11 +2292,11 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
dependencies = [
- "cloudabi",
+ "cloudabi 0.0.3",
"fuchsia-zircon",
"libc",
"rand_core 0.2.2",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -2149,7 +2305,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a"
dependencies = [
- "cloudabi",
+ "cloudabi 0.0.3",
"fuchsia-zircon",
"libc",
"rand_chacha 0.1.0",
@@ -2159,7 +2315,7 @@ dependencies = [
"rand_pcg",
"rand_xorshift",
"rustc_version",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -2267,9 +2423,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.1.40"
+version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
+checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_termios"
@@ -2304,7 +2460,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -2345,13 +2501,24 @@ dependencies = [
"libc",
"spin",
"untrusted",
- "winapi 0.3.6",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "ripemd160"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "opaque-debug",
]
[[package]]
name = "rlp"
version = "0.4.0"
-source = "git+https://github.com/CodeChain-io/rlp.git#339cc6aa02d91635199178e7c7be07b347054697"
+source = "git+https://github.com/CodeChain-io/rlp.git#64fdbc5758e05483f62fae99521520f566eaca9d"
dependencies = [
"primitives",
"rustc-hex 1.0.0",
@@ -2369,7 +2536,7 @@ dependencies = [
[[package]]
name = "rlp_derive"
version = "0.2.0"
-source = "git+https://github.com/CodeChain-io/rlp.git#339cc6aa02d91635199178e7c7be07b347054697"
+source = "git+https://github.com/CodeChain-io/rlp.git#64fdbc5758e05483f62fae99521520f566eaca9d"
dependencies = [
"proc-macro2 0.4.30",
"quote 0.6.12",
@@ -2458,7 +2625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
dependencies = [
"lazy_static 1.2.0",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -2475,9 +2642,22 @@ checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
[[package]]
name = "scopeguard"
-version = "1.0.0"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "scrypt"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
+checksum = "656c79d0e90d0ab28ac86bf3c3d10bfbbac91450d3f190113b4e76d9fec3cfdd"
+dependencies = [
+ "byte-tools",
+ "byteorder",
+ "hmac",
+ "pbkdf2",
+ "sha2",
+]
[[package]]
name = "secp256k1"
@@ -2584,9 +2764,9 @@ dependencies = [
[[package]]
name = "sha-1"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
+checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [
"block-buffer",
"digest",
@@ -2594,6 +2774,31 @@ dependencies = [
"opaque-debug",
]
+[[package]]
+name = "sha2"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "fake-simd",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sha3"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf"
+dependencies = [
+ "block-buffer",
+ "byte-tools",
+ "digest",
+ "keccak",
+ "opaque-debug",
+]
+
[[package]]
name = "shell32-sys"
version = "0.1.2"
@@ -2647,6 +2852,12 @@ dependencies = [
"unreachable",
]
+[[package]]
+name = "smallvec"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f"
+
[[package]]
name = "snap"
version = "0.2.4"
@@ -2666,7 +2877,7 @@ dependencies = [
"cfg-if",
"libc",
"redox_syscall",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -2687,6 +2898,15 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
+[[package]]
+name = "stream-cipher"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "string"
version = "0.1.3"
@@ -2699,6 +2919,12 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
+[[package]]
+name = "subtle"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
+
[[package]]
name = "syn"
version = "0.13.11"
@@ -2769,7 +2995,7 @@ dependencies = [
"rand 0.7.2",
"redox_syscall",
"remove_dir_all",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -2827,7 +3053,7 @@ checksum = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
dependencies = [
"libc",
"redox_syscall",
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -3094,8 +3320,8 @@ dependencies = [
[[package]]
name = "trie-standardmap"
-version = "0.2.0"
-source = "git+https://github.com/CodeChain-io/trie-standardmap.git#f2cdd24acb7f00e44566d86af6102c5d16b02921"
+version = "0.3.0"
+source = "git+https://github.com/CodeChain-io/trie-standardmap.git#190b7a3b43adc063e0d7c5043afc1ff9d981c870"
dependencies = [
"codechain-crypto",
"primitives",
@@ -3247,14 +3473,12 @@ dependencies = [
[[package]]
name = "vergen"
-version = "2.0.0"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a16834fc61e1492c07dae49b6c14b55f8b1d43a5f5f9e9a2ecc063f47b9f93c"
+checksum = "4ce50d8996df1f85af15f2cd8d33daae6e479575123ef4314a51a70a230739cb"
dependencies = [
"bitflags",
"chrono",
- "error-chain",
- "getset",
]
[[package]]
@@ -3294,9 +3518,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
[[package]]
name = "winapi"
-version = "0.3.6"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
@@ -3320,7 +3544,7 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab"
dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -3335,7 +3559,7 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.9",
]
[[package]]
@@ -3344,7 +3568,7 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
dependencies = [
- "winapi 0.3.6",
+ "winapi 0.3.9",
"winapi-util",
]
diff --git a/Cargo.toml b/Cargo.toml
index 753c49c770..36f1b480af 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,7 +18,7 @@ edition = "2018"
app_dirs = "^1.2.1"
clap = { version = "2", features = ["yaml"] }
codechain-core = { path = "core" }
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
codechain-discovery = { path = "discovery" }
codechain-logger = { path = "util/logger" }
codechain-key = { path = "key" }
@@ -41,8 +41,9 @@ log = "0.4.6"
env_logger = "0.5.3"
never-type = "0.1.0"
panic_hook = { path = "util/panic_hook" }
-parking_lot = "0.6.0"
+parking_lot = "0.11.0"
primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" }
+rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.4" }
rpassword = "2.0.0"
rustc-serialize = "0.3"
serde = "1.0"
@@ -53,7 +54,7 @@ toml = "0.4"
cidr = "0.0.4"
[build-dependencies]
-vergen = "2"
+vergen = "3"
[[bin]]
path = "codechain/main.rs"
diff --git a/build.rs b/build.rs
index deadea443d..7848e973d0 100644
--- a/build.rs
+++ b/build.rs
@@ -14,20 +14,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-extern crate vergen;
-
-use vergen::{ConstantsFlags, Result, Vergen};
+use vergen::{generate_cargo_keys, ConstantsFlags};
fn main() {
- gen_constants().expect("Unable to generate vergen constants!");
-}
-
-fn gen_constants() -> Result<()> {
- let vergen = Vergen::new(ConstantsFlags::all())?;
-
- for (k, v) in vergen.build_info() {
- println!("cargo:rustc-env={}={}", k.name(), v);
- }
-
- Ok(())
+ generate_cargo_keys(ConstantsFlags::all()).expect("Unable to generate vergen constants!");
}
diff --git a/codechain/auto_self_nominate.rs b/codechain/auto_self_nominate.rs
new file mode 100644
index 0000000000..70c616706a
--- /dev/null
+++ b/codechain/auto_self_nominate.rs
@@ -0,0 +1,203 @@
+// Copyright 2020 Kodebox, Inc.
+// This file is part of CodeChain.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+use crate::config::load_config;
+use ccore::stake::Action::SelfNominate;
+use ccore::stake::{Banned, Candidates, Jail, CUSTOM_ACTION_HANDLER_ID};
+use ccore::{
+ AccountProvider, AccountProviderError, BlockId, ConsensusClient, SignedTransaction, UnverifiedTransaction,
+};
+use ckey::PlatformAddress;
+use ckey::{Address, Public, Signature};
+use ckeystore::DecryptedAccount;
+use clap::ArgMatches;
+use codechain_types::transaction::{Action, Transaction};
+use primitives::{Bytes, H256};
+use rlp::Encodable;
+use std::sync::Arc;
+use std::thread;
+use std::time::Duration;
+
+const NEED_NOMINATION_UNDER_TERM_LEFT: u64 = 3;
+#[derive(Clone)]
+struct SelfSigner {
+ account_provider: Arc,
+ signer: Option<(Address, Public)>,
+ decrypted_account: Option,
+}
+impl SelfSigner {
+ pub fn new(ap: Arc, address: Address) -> Self {
+ let public = {
+ let account = ap.get_unlocked_account(&address).expect("The address must be registered in AccountProvider");
+ account.public().expect("Cannot get public from account")
+ };
+ Self {
+ account_provider: ap,
+ signer: Some((address, public)),
+ decrypted_account: None,
+ }
+ }
+
+ pub fn sign_ecdsa(&self, hash: H256) -> Result {
+ let address = self.signer.map(|(address, _public)| address).unwrap_or_else(Default::default);
+ let result = match &self.decrypted_account {
+ Some(account) => account.sign(&hash)?,
+ None => {
+ let account = self.account_provider.get_unlocked_account(&address)?;
+ account.sign(&hash)?
+ }
+ };
+ Ok(result)
+ }
+
+ pub fn address(&self) -> Option<&Address> {
+ self.signer.as_ref().map(|(address, _)| address)
+ }
+}
+
+pub struct AutoSelfNomination {
+ client: Arc,
+ signer: SelfSigner,
+}
+
+impl AutoSelfNomination {
+ pub fn new(client: Arc, ap: Arc, address: Address) -> Arc {
+ Arc::new(Self {
+ client,
+ signer: SelfSigner::new(ap, address),
+ })
+ }
+
+ pub fn send_self_nominate_transaction(&self, matches: &ArgMatches) {
+ let config = load_config(matches).unwrap();
+ let account_address = config.mining.engine_signer.unwrap();
+ let default_metadata = config.mining.self_nomination_metadata.unwrap();
+ let target_deposit = config.mining.self_target_deposit.unwrap();
+ let interval = config.mining.self_nomination_interval.unwrap();
+ let self_client = self.client.clone();
+ let self_signer = self.signer.clone();
+ thread::Builder::new()
+ .name("Auto Self Nomination".to_string())
+ .spawn(move || loop {
+ AutoSelfNomination::send(
+ &self_client,
+ &self_signer,
+ &account_address,
+ &default_metadata,
+ target_deposit,
+ );
+ thread::sleep(Duration::from_millis(interval));
+ })
+ .unwrap();
+ }
+
+ fn send(
+ client: &Arc,
+ signer: &SelfSigner,
+ account_address: &PlatformAddress,
+ metadata: &str,
+ targetdep: u64,
+ ) {
+ let metabytes = metadata.rlp_bytes();
+ let mut dep = targetdep;
+ let address = account_address.address();
+ let block_id = BlockId::Latest;
+ let state = client.state_at(block_id).unwrap();
+ let current_term = client.current_term_id(block_id).unwrap();
+ let banned = Banned::load_from_state(&state).unwrap();
+ if banned.is_banned(address) {
+ cwarn!(ENGINE, "Account is banned");
+ return
+ }
+ let jailed = Jail::load_from_state(&state).unwrap();
+ if jailed.get_prisoner(&address).is_some() {
+ let prisoner = jailed.get_prisoner(&address).unwrap();
+
+ if prisoner.custody_until <= (current_term) {
+ cwarn!(ENGINE, "Account is still in custody");
+ return
+ }
+ }
+ let candidate = Candidates::load_from_state(&state).unwrap();
+ if candidate.get_candidate(&address).is_some() {
+ let candidate_need_nomination = candidate.get_candidate(&address).unwrap();
+ if candidate_need_nomination.nomination_ends_at + NEED_NOMINATION_UNDER_TERM_LEFT <= current_term {
+ cdebug!(
+ ENGINE,
+ "No need self nominate. nomination_ends_at: {}, current_term: {}",
+ candidate_need_nomination.nomination_ends_at,
+ current_term
+ );
+ return
+ }
+ if candidate_need_nomination.deposit.lt(&targetdep) {
+ dep = targetdep.min(targetdep);
+ } else {
+ dep = 0 as u64;
+ }
+ }
+
+ AutoSelfNomination::self_nomination_transaction(&client, &signer, dep, metabytes);
+ }
+
+ fn self_nomination_transaction(
+ client: &Arc,
+ signer: &SelfSigner,
+ deposit: u64,
+ metadata: Bytes,
+ ) {
+ let network_id = client.network_id();
+ let seq = match signer.address() {
+ Some(address) => client.latest_seq(address),
+ None => {
+ cwarn!(ENGINE, "Signer was not assigned");
+ return
+ }
+ };
+ let selfnominate = SelfNominate {
+ deposit,
+ metadata,
+ };
+ let tx = Transaction {
+ seq,
+ fee: 0,
+ network_id,
+ action: Action::Custom {
+ handler_id: CUSTOM_ACTION_HANDLER_ID,
+ bytes: selfnominate.rlp_bytes(),
+ },
+ };
+
+ let signature = match signer.sign_ecdsa(*tx.hash()) {
+ Ok(signature) => signature,
+ Err(e) => {
+ cerror!(ENGINE, "Could not sign the message:{}", e);
+ return
+ }
+ };
+ let unverified = UnverifiedTransaction::new(tx, signature);
+ let signed = SignedTransaction::try_new(unverified).expect("secret is valid so it's recoverable");
+
+ match client.queue_own_transaction(signed) {
+ Ok(_) => {
+ cinfo!(ENGINE, "Send self nominate transaction");
+ }
+ Err(e) => {
+ cerror!(ENGINE, "Failed to queue self nominate transaction: {}", e);
+ }
+ }
+ }
+}
diff --git a/codechain/codechain.yml b/codechain/codechain.yml
index 0558880d58..00a88b0a71 100644
--- a/codechain/codechain.yml
+++ b/codechain/codechain.yml
@@ -160,6 +160,21 @@ args:
long: engine-signer
help: Specify the address which should be used to sign consensus messages and issue blocks.
takes_value: true
+ - self-nomination-metadata:
+ long: self-nomination-metadata
+ help: Specify metadata which should be used to do self nomination.
+ takes_value: true
+ - self-nomination-target-deposit:
+ long: self-nomination-target-deposit
+ help: Specify the amount of deposit need to provide deposite for candidatory in the process of self nomination.
+ takes_value: true
+ - self-nomination-interval:
+ long: self-nomination-interval
+ help: Specify the time(ms) interval for self nomination process.
+ takes_value: true
+ - enable-auto-self-nomination:
+ long: enable-auto-self-nomination
+ help: Run auto self nomination thread.
- password-path:
long: password-path
help: Specify the password file path.
diff --git a/codechain/config/mod.rs b/codechain/config/mod.rs
index d126f37692..c6f0a09d0a 100644
--- a/codechain/config/mod.rs
+++ b/codechain/config/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2018-2019 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
mod chain_type;
-use ccore::{MemPoolFees, MinerOptions, StratumConfig, TimeGapParams};
+use ccore::{MemPoolMinFees, MinerOptions, StratumConfig, TimeGapParams};
use cidr::IpCidr;
use ckey::PlatformAddress;
use clap;
@@ -74,7 +74,7 @@ impl Config {
None => unreachable!(),
};
- let mem_pool_fees = MemPoolFees::create_from_options(
+ let mem_pool_min_fees = MemPoolMinFees::create_from_options(
self.mining.min_pay_transaction_cost,
self.mining.min_set_regular_key_transaction_cost,
self.mining.min_create_shard_transaction_cost,
@@ -107,7 +107,7 @@ impl Config {
reseal_max_period: Duration::from_millis(self.mining.reseal_max_period.unwrap()),
no_reseal_timer: self.mining.no_reseal_timer.unwrap(),
work_queue_size: self.mining.work_queue_size.unwrap(),
- mem_pool_fees,
+ mem_pool_min_fees,
})
}
@@ -236,6 +236,10 @@ pub struct Mining {
pub engine_signer: Option,
pub mem_pool_size: Option,
pub mem_pool_mem_limit: Option,
+ pub self_nomination_metadata: Option,
+ pub self_target_deposit: Option,
+ pub self_nomination_enable: bool,
+ pub self_nomination_interval: Option,
pub mem_pool_fee_bump_shift: Option,
pub allow_create_shard: Option,
pub notify_work: Option>,
@@ -411,6 +415,15 @@ impl Mining {
if other.engine_signer.is_some() {
self.engine_signer = other.engine_signer;
}
+ if other.self_nomination_metadata.is_some() {
+ self.self_nomination_metadata = other.self_nomination_metadata.clone();
+ }
+ if other.self_target_deposit.is_some() {
+ self.self_target_deposit = other.self_target_deposit;
+ }
+ if other.self_nomination_interval.is_some() {
+ self.self_nomination_interval = other.self_nomination_interval;
+ }
if other.mem_pool_size.is_some() {
self.mem_pool_size = other.mem_pool_size;
}
@@ -492,6 +505,22 @@ impl Mining {
if let Some(engine_signer) = matches.value_of("engine-signer") {
self.engine_signer = Some(engine_signer.parse().map_err(|_| "Invalid address format")?);
}
+ if let Some(self_nomination_metadata) = matches.value_of("self-nomination-metadata") {
+ self.self_nomination_metadata =
+ Some(self_nomination_metadata.parse().map_err(|_| "Invalid self nomination metadata format")?);
+ }
+ if let Some(self_nomination_target_deposit) = matches.value_of("self-nomination-target-deposit") {
+ self.self_target_deposit = Some(
+ self_nomination_target_deposit.parse().map_err(|_| "Invalid self nomination target deposit format")?,
+ );
+ }
+ if let Some(self_nomination_interval) = matches.value_of("self-nomination-interval") {
+ self.self_nomination_interval =
+ Some(self_nomination_interval.parse().map_err(|_| "Invalid self nomination interval format")?);
+ }
+ if matches.is_present("enable-auto-self-nomination") {
+ self.self_nomination_enable = true;
+ }
if matches.is_present("no-miner") {
self.author = None;
self.engine_signer = None;
diff --git a/codechain/config/presets/config.dev.toml b/codechain/config/presets/config.dev.toml
index 2b8890b4f7..1d700136d8 100644
--- a/codechain/config/presets/config.dev.toml
+++ b/codechain/config/presets/config.dev.toml
@@ -15,6 +15,7 @@ reseal_min_period = 0
reseal_max_period = 120000
no_reseal_timer = false
work_queue_size = 20
+self_nomination_enable = false
allowed_past_gap = 30000
allowed_future_gap = 5000
diff --git a/codechain/config/presets/config.prod.toml b/codechain/config/presets/config.prod.toml
index b67e2746bb..dcd415ea82 100644
--- a/codechain/config/presets/config.prod.toml
+++ b/codechain/config/presets/config.prod.toml
@@ -6,6 +6,7 @@ chain = "mainnet"
[mining]
mem_pool_mem_limit = 512 # MB
mem_pool_size = 524288
+self_nomination_enable = false
mem_pool_fee_bump_shift = 3 # 12.5%
allow_create_shard = false
notify_work = []
diff --git a/codechain/main.rs b/codechain/main.rs
index 4c7f6691f8..e372f5027f 100644
--- a/codechain/main.rs
+++ b/codechain/main.rs
@@ -54,6 +54,7 @@ extern crate primitives;
extern crate rpassword;
extern crate toml;
+mod auto_self_nominate;
mod config;
mod constants;
mod dummy_network_service;
diff --git a/codechain/run_node.rs b/codechain/run_node.rs
index c6f0e4e4b8..e0c49b1b8d 100644
--- a/codechain/run_node.rs
+++ b/codechain/run_node.rs
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
+use crate::auto_self_nominate::AutoSelfNomination;
use crate::config::{self, load_config};
use crate::constants::{DEFAULT_DB_PATH, DEFAULT_KEYS_PATH};
use crate::dummy_network_service::DummyNetworkService;
@@ -21,8 +22,9 @@ use crate::json::PasswordFile;
use crate::rpc::{rpc_http_start, rpc_ipc_start, rpc_ws_start};
use crate::rpc_apis::ApiDependencies;
use ccore::{
- AccountProvider, AccountProviderError, BlockId, ChainNotify, Client, ClientConfig, ClientService, EngineClient,
- EngineInfo, EngineType, Miner, MinerService, PeerDb, Scheme, Stratum, StratumConfig, StratumError, NUM_COLUMNS,
+ AccountProvider, AccountProviderError, BlockId, ChainNotify, Client, ClientConfig, ClientService, ConsensusClient,
+ EngineClient, EngineInfo, EngineType, Miner, MinerService, PeerDb, Scheme, Stratum, StratumConfig, StratumError,
+ NUM_COLUMNS,
};
use cdiscovery::{Config, Discovery};
use ckey::{Address, NetworkId, PlatformAddress};
@@ -69,6 +71,11 @@ fn network_start(
Ok(service)
}
+fn self_nominate_start(c: Arc, matches: &ArgMatches, ap: Arc, address: Address) {
+ let auto_self_nominate = AutoSelfNomination::new(c, ap, address);
+ auto_self_nominate.send_self_nominate_transaction(matches);
+}
+
fn discovery_start(
service: &NetworkService,
cfg: &config::Network,
@@ -124,7 +131,7 @@ fn new_miner(
ap: Arc,
db: Arc,
) -> Result, String> {
- let miner = Miner::new(config.miner_options()?, scheme, Some(ap), db);
+ let miner = Miner::new(config.miner_options()?, scheme, ap, db);
match miner.engine_type() {
EngineType::PoW => match &config.mining.author {
@@ -138,8 +145,7 @@ fn new_miner(
Some(ref engine_signer) => match miner.set_author((*engine_signer).into_address()) {
Err(AccountProviderError::NotUnlocked) => {
return Err(
- "The account is not unlocked. Specify the password path using --password-path option."
- .to_string(),
+ format!("The account {} is not unlocked. The key file should exist in the keys_path directory, and the account's password should exist in the password_path file.", engine_signer)
)
}
Err(e) => return Err(format!("{}", e)),
@@ -316,6 +322,12 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> {
Arc::new(DummyNetworkService::new())
}
};
+ if config.mining.self_nomination_enable {
+ let c = client.client();
+ let address = miner.get_author_address();
+ let accountp = ap.clone();
+ self_nominate_start(c, matches, accountp, address);
+ }
let rpc_apis_deps = ApiDependencies {
client: client.client(),
diff --git a/codechain/test_lock.rs b/codechain/test_lock.rs
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/core/Cargo.toml b/core/Cargo.toml
index ee8ec36be0..cf78db5961 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -5,8 +5,8 @@ authors = ["CodeChain Team "]
edition = "2018"
[dependencies]
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
-codechain-db = { git = "https://github.com/CodeChain-io/rust-codechain-db.git", version = "0.1" }
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
+codechain-db = { git = "https://github.com/CodeChain-io/rust-codechain-db.git", version = "0.2" }
codechain-io = { path = "../util/io" }
codechain-json = { path = "../json" }
codechain-key = { path = "../key" }
@@ -27,9 +27,9 @@ kvdb-memorydb = "0.1"
linked-hash-map = "0.5"
log = "0.4.6"
lru-cache = "0.1.2"
-merkle-trie = { git = "https://github.com/CodeChain-io/rust-merkle-trie.git", version = "0.1" }
+merkle-trie = { git = "https://github.com/CodeChain-io/rust-merkle-trie.git", version = "0.4" }
num-rational = "0.2.1"
-parking_lot = "0.6.0"
+parking_lot = "0.11.0"
primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" }
rand = "0.6.1"
rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.4" }
diff --git a/core/src/block.rs b/core/src/block.rs
index ebd3484fcf..421c840883 100644
--- a/core/src/block.rs
+++ b/core/src/block.rs
@@ -34,7 +34,7 @@ use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
use std::collections::HashSet;
/// A block, encoded as it is on the block chain.
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone)]
pub struct Block {
/// The header of this block
pub header: Header,
@@ -152,7 +152,6 @@ impl<'x> OpenBlock<'x> {
pub fn push_transaction(
&mut self,
tx: SignedTransaction,
- h: Option,
client: &C,
parent_block_number: BlockNumber,
parent_block_timestamp: u64,
@@ -173,7 +172,7 @@ impl<'x> OpenBlock<'x> {
self.block.header.timestamp(),
) {
Ok(()) => {
- self.block.transactions_set.insert(h.unwrap_or(hash));
+ self.block.transactions_set.insert(hash);
self.block.transactions.push(tx);
None
}
@@ -200,7 +199,7 @@ impl<'x> OpenBlock<'x> {
parent_block_timestamp: u64,
) -> Result<(), Error> {
for tx in transactions {
- self.push_transaction(tx.clone(), None, client, parent_block_number, parent_block_timestamp)?;
+ self.push_transaction(tx.clone(), client, parent_block_number, parent_block_timestamp)?;
}
Ok(())
}
diff --git a/core/src/blockchain/body_db.rs b/core/src/blockchain/body_db.rs
index 38978b1227..7b50e40663 100644
--- a/core/src/blockchain/body_db.rs
+++ b/core/src/blockchain/body_db.rs
@@ -346,9 +346,9 @@ fn tx_hash_and_address_entries(
fn tracker_and_addresses_entries(
block_hash: BlockHash,
- tx_hashes: impl IntoIterator- ,
+ transactions: impl IntoIterator
- ,
) -> impl Iterator
- {
- tx_hashes.into_iter().enumerate().filter_map(move |(index, tx)| {
+ transactions.into_iter().enumerate().filter_map(move |(index, tx)| {
tx.tracker().map(|tracker| {
(
tracker,
diff --git a/core/src/client/chain_notify.rs b/core/src/client/chain_notify.rs
index a4868a7571..cd964773a5 100644
--- a/core/src/client/chain_notify.rs
+++ b/core/src/client/chain_notify.rs
@@ -14,8 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-use cnetwork::NodeId;
-use ctypes::{BlockHash, TxHash};
+use ctypes::BlockHash;
/// Represents what has to be handled by actor listening to chain events
pub trait ChainNotify: Send + Sync {
@@ -43,9 +42,4 @@ pub trait ChainNotify: Send + Sync {
) {
// does nothing by default
}
-
- /// fires when new transactions are received from a peer
- fn transactions_received(&self, _hashes: Vec, _peer_id: NodeId) {
- // does nothing by default
- }
}
diff --git a/core/src/client/client.rs b/core/src/client/client.rs
index c9e6feb6ee..4a6965184b 100644
--- a/core/src/client/client.rs
+++ b/core/src/client/client.rs
@@ -31,16 +31,16 @@ use crate::scheme::Scheme;
use crate::service::ClientIoMessage;
use crate::transaction::{LocalizedTransaction, PendingSignedTransactions, SignedTransaction, UnverifiedTransaction};
use crate::types::{BlockId, BlockStatus, TransactionId, VerificationQueueInfo as BlockQueueInfo};
+use crate::MemPoolMinFees;
use cdb::{new_journaldb, Algorithm, AsHashDB, DatabaseError};
use cio::IoChannel;
use ckey::{Address, NetworkId, PlatformAddress, Public};
-use cnetwork::NodeId;
use cstate::{
ActionHandler, AssetScheme, FindActionHandler, OwnedAsset, StateDB, StateResult, Text, TopLevelState, TopStateView,
};
use ctimer::{TimeoutHandler, TimerApi, TimerScheduleError, TimerToken};
use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction};
-use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker, TxHash};
+use ctypes::{BlockHash, BlockNumber, CommonParams, Header, ShardId, Tracker, TxHash};
use cvm::{decode, execute, ChainTimeInfo, ScriptResult, VMConfig};
use kvdb::{DBTransaction, KeyValueDB};
use merkle_trie::Result as TrieResult;
@@ -75,6 +75,9 @@ pub struct Client {
importer: Importer,
+ /// Handles block sealing
+ miner: Arc,
+
/// Timer for reseal_min_period/reseal_max_period on miner client
reseal_timer: TimerApi,
}
@@ -103,11 +106,10 @@ impl Client {
let gb = scheme.genesis_block();
let chain = BlockChain::new(&gb, db.clone());
- scheme.check_genesis_common_params(&chain)?;
let engine = scheme.engine.clone();
- let importer = Importer::try_new(config, engine.clone(), message_channel.clone(), miner)?;
+ let importer = Importer::try_new(config, engine.clone(), message_channel.clone(), Arc::clone(&miner))?;
let genesis_accounts = scheme.genesis_accounts();
let client = Arc::new(Client {
@@ -120,6 +122,7 @@ impl Client {
queue_transactions: AtomicUsize::new(0),
genesis_accounts,
importer,
+ miner,
reseal_timer,
});
@@ -138,12 +141,6 @@ impl Client {
self.notify.write().push(target);
}
- pub fn transactions_received(&self, hashes: &[TxHash], peer_id: NodeId) {
- self.notify(|notify| {
- notify.transactions_received(hashes.to_vec(), peer_id);
- });
- }
-
pub fn new_blocks(
&self,
imported: &[BlockHash],
@@ -196,7 +193,7 @@ impl Client {
/// This is triggered by a message coming from a header queue when the header is ready for insertion
pub fn import_verified_headers(&self) -> usize {
- self.importer.import_verified_headers(self)
+ self.importer.import_verified_headers_from_queue(self)
}
/// This is triggered by a message coming from a block queue when the block is ready for insertion
@@ -206,7 +203,7 @@ impl Client {
/// This is triggered by a message coming from a engine when a new block should be created
pub fn update_sealing(&self, parent_block: BlockId, allow_empty_block: bool) {
- self.importer.miner.update_sealing(self, parent_block, allow_empty_block);
+ self.miner.update_sealing(self, parent_block, allow_empty_block);
}
fn block_hash(chain: &BlockChain, id: &BlockId) -> Option {
@@ -236,14 +233,12 @@ impl Client {
}
/// Import transactions from the IO queue
- pub fn import_queued_transactions(&self, transactions: &[Bytes], peer_id: NodeId) -> usize {
+ pub fn import_queued_transactions(&self, transactions: &[Bytes]) -> usize {
ctrace!(EXTERNAL_TX, "Importing queued");
self.queue_transactions.fetch_sub(transactions.len(), AtomicOrdering::SeqCst);
let transactions: Vec =
transactions.iter().filter_map(|bytes| Rlp::new(bytes).as_val().ok()).collect();
- let hashes: Vec<_> = transactions.iter().map(UnverifiedTransaction::hash).collect();
- self.transactions_received(&hashes, peer_id);
- let results = self.importer.miner.import_external_transactions(self, transactions);
+ let results = self.miner.import_external_transactions(self, transactions);
results.len()
}
@@ -273,7 +268,7 @@ impl Client {
}
let (enacted, retracted) = self.importer.calculate_enacted_retracted(&[route]);
- self.importer.miner.chain_new_blocks(self, &[], &[], &enacted, &retracted);
+ self.miner.chain_new_blocks(self, &[], &[], &enacted, &retracted);
self.new_blocks(&[], &[], &enacted, &retracted, &[]);
}
@@ -324,7 +319,7 @@ impl TimeoutHandler for Client {
match token {
RESEAL_MAX_TIMER_TOKEN => {
// Working in PoW only
- if self.engine().seals_internally().is_none() && !self.importer.miner.prepare_work_sealing(self) {
+ if self.engine().seals_internally().is_none() && !self.miner.prepare_work_sealing(self) {
self.update_sealing(BlockId::Latest, true);
}
}
@@ -556,7 +551,7 @@ impl EngineClient for Client {
/// Submit a seal for a block in the mining queue.
fn submit_seal(&self, block_hash: BlockHash, seal: Vec) {
- if self.importer.miner.submit_seal(self, block_hash, seal).is_err() {
+ if self.miner.submit_seal(self, block_hash, seal).is_err() {
cwarn!(CLIENT, "Wrong internal seal submission!")
}
}
@@ -645,17 +640,14 @@ impl ImportBlock for Client {
Ok(self.importer.block_queue.import(unverified)?)
}
- fn import_header(&self, bytes: Bytes) -> Result {
- let unverified = encoded::Header::new(bytes).decode();
- {
- if self.block_chain().is_known_header(&unverified.hash()) {
- return Err(BlockImportError::Import(ImportError::AlreadyInChain))
- }
+ fn import_header(&self, unverified: Header) -> Result {
+ if self.block_chain().is_known_header(&unverified.hash()) {
+ return Err(BlockImportError::Import(ImportError::AlreadyInChain))
}
Ok(self.importer.header_queue.import(unverified)?)
}
- fn import_sealed_block(&self, block: &SealedBlock) -> ImportResult {
+ fn import_generated_block(&self, block: &SealedBlock) -> ImportResult {
let h = block.header().hash();
let route = {
// scope for self.import_lock
@@ -665,14 +657,14 @@ impl ImportBlock for Client {
let block_data = block.rlp_bytes();
let header = block.header();
- self.importer.import_headers(vec![header], self, &import_lock);
+ self.importer.import_verified_headers(vec![header], self, &import_lock);
let route = self.importer.commit_block(block, header, &block_data, self);
cinfo!(CLIENT, "Imported sealed block #{} ({})", number, h);
route
};
let (enacted, retracted) = self.importer.calculate_enacted_retracted(&[route]);
- self.importer.miner.chain_new_blocks(self, &[h], &[], &enacted, &retracted);
+ self.miner.chain_new_blocks(self, &[h], &[], &enacted, &retracted);
self.new_blocks(&[h], &[], &enacted, &retracted, &[h]);
self.db().flush().expect("DB flush failed.");
Ok(h)
@@ -680,10 +672,7 @@ impl ImportBlock for Client {
fn set_min_timer(&self) {
self.reseal_timer.cancel(RESEAL_MIN_TIMER_TOKEN).expect("Reseal min timer clear succeeds");
- match self
- .reseal_timer
- .schedule_once(self.importer.miner.get_options().reseal_min_period, RESEAL_MIN_TIMER_TOKEN)
- {
+ match self.reseal_timer.schedule_once(self.miner.get_options().reseal_min_period, RESEAL_MIN_TIMER_TOKEN) {
Ok(_) => {}
Err(TimerScheduleError::TokenAlreadyScheduled) => {
// Since set_min_timer could be called in multi thread, ignore the TokenAlreadyScheduled error
@@ -694,10 +683,7 @@ impl ImportBlock for Client {
fn set_max_timer(&self) {
self.reseal_timer.cancel(RESEAL_MAX_TIMER_TOKEN).expect("Reseal max timer clear succeeds");
- match self
- .reseal_timer
- .schedule_once(self.importer.miner.get_options().reseal_max_period, RESEAL_MAX_TIMER_TOKEN)
- {
+ match self.reseal_timer.schedule_once(self.miner.get_options().reseal_max_period, RESEAL_MAX_TIMER_TOKEN) {
Ok(_) => {}
Err(TimerScheduleError::TokenAlreadyScheduled) => {
// Since set_max_timer could be called in multi thread, ignore the TokenAlreadyScheduled error
@@ -715,18 +701,18 @@ impl BlockChainClient for Client {
/// Import own transaction
fn queue_own_transaction(&self, transaction: SignedTransaction) -> Result<(), Error> {
- self.importer.miner.import_own_transaction(self, transaction)?;
+ self.miner.import_own_transaction(self, transaction)?;
Ok(())
}
- fn queue_transactions(&self, transactions: Vec, peer_id: NodeId) {
+ fn queue_transactions(&self, transactions: Vec) {
let queue_size = self.queue_transactions.load(AtomicOrdering::Relaxed);
ctrace!(EXTERNAL_TX, "Queue size: {}", queue_size);
if queue_size > MAX_MEM_POOL_SIZE {
cwarn!(EXTERNAL_TX, "Ignoring {} transactions: queue is full", transactions.len());
} else {
let len = transactions.len();
- match self.io_channel.lock().send(ClientIoMessage::NewTransactions(transactions, peer_id)) {
+ match self.io_channel.lock().send(ClientIoMessage::NewTransactions(transactions)) {
Ok(_) => {
self.queue_transactions.fetch_add(len, AtomicOrdering::SeqCst);
}
@@ -738,26 +724,26 @@ impl BlockChainClient for Client {
}
fn delete_all_pending_transactions(&self) {
- self.importer.miner.delete_all_pending_transactions();
+ self.miner.delete_all_pending_transactions();
}
fn ready_transactions(&self, range: Range) -> PendingSignedTransactions {
- self.importer.miner.ready_transactions(range)
+ self.miner.ready_transactions(range)
}
fn count_pending_transactions(&self, range: Range) -> usize {
- self.importer.miner.count_pending_transactions(range)
+ self.miner.count_pending_transactions(range)
}
fn future_included_count_pending_transactions(&self, range: Range) -> usize {
- self.importer.miner.future_included_count_pending_transactions(range)
+ self.miner.future_included_count_pending_transactions(range)
}
fn future_ready_transactions(&self, range: Range) -> PendingSignedTransactions {
- self.importer.miner.future_ready_transactions(range)
+ self.miner.future_ready_transactions(range)
}
fn is_pending_queue_empty(&self) -> bool {
- self.importer.miner.status().transactions_in_pending_queue == 0
+ self.miner.status().transactions_in_pending_queue == 0
}
fn block_number(&self, id: &BlockId) -> Option {
@@ -907,23 +893,27 @@ impl BlockProducer for Client {
impl MiningBlockChainClient for Client {
fn get_malicious_users(&self) -> Vec {
- self.importer.miner.get_malicious_users()
+ self.miner.get_malicious_users()
}
fn release_malicious_users(&self, prisoner_vec: Vec) {
- self.importer.miner.release_malicious_users(prisoner_vec)
+ self.miner.release_malicious_users(prisoner_vec)
}
fn imprison_malicious_users(&self, prisoner_vec: Vec) {
- self.importer.miner.imprison_malicious_users(prisoner_vec)
+ self.miner.imprison_malicious_users(prisoner_vec)
}
fn get_immune_users(&self) -> Vec {
- self.importer.miner.get_immune_users()
+ self.miner.get_immune_users()
}
fn register_immune_users(&self, immune_user_vec: Vec) {
- self.importer.miner.register_immune_users(immune_user_vec)
+ self.miner.register_immune_users(immune_user_vec)
+ }
+
+ fn mem_pool_min_fees(&self) -> MemPoolMinFees {
+ self.miner.get_options().mem_pool_min_fees
}
}
diff --git a/core/src/client/config.rs b/core/src/client/config.rs
index f64b679609..e1afbb6097 100644
--- a/core/src/client/config.rs
+++ b/core/src/client/config.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-use crate::verification::{QueueConfig, VerifierType};
+use crate::verification::QueueConfig;
use kvdb_rocksdb::CompactionProfile;
use std::path::Path;
use std::str::FromStr;
@@ -71,8 +71,6 @@ pub struct ClientConfig {
pub db_compaction: DatabaseCompactionProfile,
/// State db cache-size.
pub state_cache_size: usize,
- /// Type of block verifier used by client.
- pub verifier_type: VerifierType,
}
impl Default for ClientConfig {
@@ -84,7 +82,6 @@ impl Default for ClientConfig {
db_cache_size: Default::default(),
db_compaction: Default::default(),
state_cache_size: DEFAULT_STATE_CACHE_SIZE as usize * mb,
- verifier_type: Default::default(),
}
}
}
diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs
index 28a080ff6b..da46a1734a 100644
--- a/core/src/client/importer.rs
+++ b/core/src/client/importer.rs
@@ -41,7 +41,7 @@ pub struct Importer {
pub import_lock: Mutex<()>, // FIXME Maybe wrap the whole `Importer` instead?
/// Used to verify blocks
- pub verifier: Box>,
+ pub verifier: Verifier,
/// Queue containing pending blocks
pub block_queue: BlockQueue,
@@ -50,7 +50,7 @@ pub struct Importer {
pub header_queue: HeaderQueue,
/// Handles block sealing
- pub miner: Arc,
+ miner: Arc,
/// CodeChain engine to be used during import
pub engine: Arc,
@@ -63,19 +63,13 @@ impl Importer {
message_channel: IoChannel,
miner: Arc,
) -> Result {
- let block_queue = BlockQueue::new(
- &config.queue,
- engine.clone(),
- message_channel.clone(),
- config.verifier_type.verifying_seal(),
- );
+ let block_queue = BlockQueue::new(&config.queue, engine.clone(), message_channel.clone(), true);
- let header_queue =
- HeaderQueue::new(&config.queue, engine.clone(), message_channel, config.verifier_type.verifying_seal());
+ let header_queue = HeaderQueue::new(&config.queue, engine.clone(), message_channel, true);
Ok(Importer {
import_lock: Mutex::new(()),
- verifier: verification::new(config.verifier_type),
+ verifier: Verifier::new(),
block_queue,
header_queue,
miner,
@@ -99,7 +93,7 @@ impl Importer {
{
let headers: Vec<&Header> = blocks.iter().map(|block| &block.header).collect();
- self.import_headers(headers, client, &import_lock);
+ self.import_verified_headers(headers, client, &import_lock);
}
for block in blocks {
@@ -293,14 +287,14 @@ impl Importer {
}
/// This is triggered by a message coming from a header queue when the header is ready for insertion
- pub fn import_verified_headers(&self, client: &Client) -> usize {
+ pub fn import_verified_headers_from_queue(&self, client: &Client) -> usize {
const MAX_HEADERS_TO_IMPORT: usize = 1_000;
let lock = self.import_lock.lock();
let headers = self.header_queue.drain(MAX_HEADERS_TO_IMPORT);
- self.import_headers(&headers, client, &lock)
+ self.import_verified_headers(&headers, client, &lock)
}
- pub fn import_headers<'a>(
+ pub fn import_verified_headers<'a>(
&'a self,
headers: impl IntoIterator
- ,
client: &Client,
diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs
index 32aea185c4..aa4766ecd1 100644
--- a/core/src/client/mod.rs
+++ b/core/src/client/mod.rs
@@ -32,14 +32,14 @@ use crate::blockchain_info::BlockChainInfo;
use crate::consensus::EngineError;
use crate::encoded;
use crate::error::{BlockImportError, Error as GenericError};
+use crate::miner::MemPoolMinFees;
use crate::transaction::{LocalizedTransaction, PendingSignedTransactions, SignedTransaction};
use crate::types::{BlockId, BlockStatus, TransactionId, VerificationQueueInfo as BlockQueueInfo};
use cdb::DatabaseError;
use ckey::{Address, NetworkId, PlatformAddress, Public};
-use cnetwork::NodeId;
use cstate::{AssetScheme, FindActionHandler, OwnedAsset, StateResult, Text, TopLevelState, TopStateView};
use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction};
-use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker, TxHash};
+use ctypes::{BlockHash, BlockNumber, CommonParams, Header, ShardId, Tracker, TxHash};
use cvm::ChainTimeInfo;
use kvdb::KeyValueDB;
use merkle_trie::Result as TrieResult;
@@ -197,10 +197,10 @@ pub trait ImportBlock {
fn import_block(&self, bytes: Bytes) -> Result;
/// Import a header into the blockchain
- fn import_header(&self, bytes: Bytes) -> Result;
+ fn import_header(&self, header: Header) -> Result;
/// Import sealed block. Skips all verifications.
- fn import_sealed_block(&self, block: &SealedBlock) -> ImportResult;
+ fn import_generated_block(&self, block: &SealedBlock) -> ImportResult;
/// Set reseal min timer as reseal_min_period, for creating blocks with transactions which are pending because of reseal_min_period
fn set_min_timer(&self);
@@ -217,7 +217,7 @@ pub trait BlockChainClient: Sync + Send + AccountData + BlockChainTrait + Import
fn queue_own_transaction(&self, transaction: SignedTransaction) -> Result<(), GenericError>;
/// Queue transactions for importing.
- fn queue_transactions(&self, transactions: Vec, peer_id: NodeId);
+ fn queue_transactions(&self, transactions: Vec);
/// Delete all pending transactions.
fn delete_all_pending_transactions(&self);
@@ -294,6 +294,8 @@ pub trait MiningBlockChainClient: BlockChainClient + BlockProducer + FindActionH
/// Append designated users to the immune user list.
fn register_immune_users(&self, immune_user_vec: Vec);
+
+ fn mem_pool_min_fees(&self) -> MemPoolMinFees;
}
/// Provides methods to access database.
diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs
index e30e84d069..43e164b636 100644
--- a/core/src/client/test_client.rs
+++ b/core/src/client/test_client.rs
@@ -41,13 +41,12 @@ use crate::consensus::EngineError;
use crate::db::{COL_STATE, NUM_COLUMNS};
use crate::encoded;
use crate::error::{BlockImportError, Error as GenericError};
-use crate::miner::{Miner, MinerService, TransactionImportResult};
+use crate::miner::{MemPoolMinFees, Miner, MinerService, TransactionImportResult};
use crate::scheme::Scheme;
use crate::transaction::{LocalizedTransaction, PendingSignedTransactions, SignedTransaction};
use crate::types::{BlockId, TransactionId, VerificationQueueInfo as QueueInfo};
use cdb;
use ckey::{public_to_address, Address, Generator, KeyPair, NetworkId, PlatformAddress, Private, Public, Random};
-use cnetwork::NodeId;
use cstate::tests::helpers::empty_top_state;
use cstate::{FindActionHandler, StateDB, TopLevelState};
use ctimer::{TimeoutHandler, TimerToken};
@@ -151,7 +150,7 @@ impl TestBlockChainClient {
seqs: RwLock::new(HashMap::new()),
storage: RwLock::new(HashMap::new()),
queue_size: AtomicUsize::new(0),
- miner: Arc::new(Miner::with_scheme(&scheme, db)),
+ miner: Arc::new(Miner::with_scheme_for_test(&scheme, db)),
scheme,
latest_block_timestamp: RwLock::new(10_000_000),
history: RwLock::new(None),
@@ -378,6 +377,10 @@ impl MiningBlockChainClient for TestBlockChainClient {
fn register_immune_users(&self, immune_user_vec: Vec) {
self.miner.register_immune_users(immune_user_vec)
}
+
+ fn mem_pool_min_fees(&self) -> MemPoolMinFees {
+ self.miner.get_options().mem_pool_min_fees
+ }
}
impl AccountData for TestBlockChainClient {
@@ -505,11 +508,11 @@ impl ImportBlock for TestBlockChainClient {
Ok(h)
}
- fn import_header(&self, _bytes: Bytes) -> Result {
+ fn import_header(&self, _bytes: BlockHeader) -> Result {
unimplemented!()
}
- fn import_sealed_block(&self, _block: &SealedBlock) -> ImportResult {
+ fn import_generated_block(&self, _block: &SealedBlock) -> ImportResult {
Ok(H256::default().into())
}
@@ -536,7 +539,7 @@ impl BlockChainClient for TestBlockChainClient {
Ok(())
}
- fn queue_transactions(&self, transactions: Vec, _peer_id: NodeId) {
+ fn queue_transactions(&self, transactions: Vec) {
// import right here
let transactions = transactions.into_iter().filter_map(|bytes| Rlp::new(&bytes).as_val().ok()).collect();
self.miner.import_external_transactions(self, transactions);
diff --git a/core/src/consensus/blake_pow/mod.rs b/core/src/consensus/blake_pow/mod.rs
index 386dfa36bf..8df5d2c58e 100644
--- a/core/src/consensus/blake_pow/mod.rs
+++ b/core/src/consensus/blake_pow/mod.rs
@@ -83,10 +83,6 @@ impl BlakePoW {
}
impl ConsensusEngine for BlakePoW {
- fn name(&self) -> &str {
- "BlakePoW"
- }
-
fn machine(&self) -> &CodeChainMachine {
&self.machine
}
diff --git a/core/src/consensus/cuckoo/mod.rs b/core/src/consensus/cuckoo/mod.rs
index 6aefe7c5e6..5e3dd243ee 100644
--- a/core/src/consensus/cuckoo/mod.rs
+++ b/core/src/consensus/cuckoo/mod.rs
@@ -89,10 +89,6 @@ impl Cuckoo {
}
impl ConsensusEngine for Cuckoo {
- fn name(&self) -> &str {
- "Cuckoo"
- }
-
fn machine(&self) -> &CodeChainMachine {
&self.machine
}
@@ -210,7 +206,6 @@ mod tests {
fn has_valid_metadata() {
let engine = Scheme::new_test_cuckoo().engine;
- assert_eq!(engine.name(), "Cuckoo");
assert_eq!(engine.engine_type(), EngineType::PoW);
}
diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs
index 7adf4d6328..ed55ba6818 100644
--- a/core/src/consensus/mod.rs
+++ b/core/src/consensus/mod.rs
@@ -18,7 +18,7 @@ mod bit_set;
mod blake_pow;
mod cuckoo;
mod null_engine;
-mod signer;
+pub(crate) mod signer;
mod simple_poa;
mod solo;
pub mod stake;
@@ -138,9 +138,6 @@ impl EngineType {
/// A consensus mechanism for the chain.
pub trait ConsensusEngine: Sync + Send {
- /// The name of this engine.
- fn name(&self) -> &str;
-
/// Get access to the underlying state machine.
fn machine(&self) -> &CodeChainMachine;
diff --git a/core/src/consensus/null_engine/mod.rs b/core/src/consensus/null_engine/mod.rs
index cbd1a07bc7..9fba363cdf 100644
--- a/core/src/consensus/null_engine/mod.rs
+++ b/core/src/consensus/null_engine/mod.rs
@@ -42,10 +42,6 @@ impl NullEngine {
}
impl ConsensusEngine for NullEngine {
- fn name(&self) -> &str {
- "NullEngine"
- }
-
fn machine(&self) -> &CodeChainMachine {
&self.machine
}
diff --git a/core/src/consensus/simple_poa/mod.rs b/core/src/consensus/simple_poa/mod.rs
index 4db084d9cf..75d08f543c 100644
--- a/core/src/consensus/simple_poa/mod.rs
+++ b/core/src/consensus/simple_poa/mod.rs
@@ -73,10 +73,6 @@ fn verify_external(header: &Header, validators: &dyn ValidatorSet) -> Result<(),
}
impl ConsensusEngine for SimplePoA {
- fn name(&self) -> &str {
- "SimplePoA"
- }
-
fn machine(&self) -> &CodeChainMachine {
&self.machine
}
@@ -159,12 +155,6 @@ mod tests {
use super::*;
- #[test]
- fn has_valid_metadata() {
- let engine = Scheme::new_test_simple_poa().engine;
- assert!(!engine.name().is_empty());
- }
-
#[test]
fn fail_to_verify_signature_when_seal_is_invalid() {
let engine = Scheme::new_test_simple_poa().engine;
diff --git a/core/src/consensus/solo/mod.rs b/core/src/consensus/solo/mod.rs
index 69cead2f84..5faa74e6e1 100644
--- a/core/src/consensus/solo/mod.rs
+++ b/core/src/consensus/solo/mod.rs
@@ -61,10 +61,6 @@ impl Solo {
}
impl ConsensusEngine for Solo {
- fn name(&self) -> &str {
- "Solo"
- }
-
fn machine(&self) -> &CodeChainMachine {
&self.machine
}
diff --git a/core/src/consensus/stake/action_data.rs b/core/src/consensus/stake/action_data.rs
index 170774b541..d798f0fe49 100644
--- a/core/src/consensus/stake/action_data.rs
+++ b/core/src/consensus/stake/action_data.rs
@@ -510,6 +510,9 @@ impl Candidates {
pub fn len(&self) -> usize {
self.0.len()
}
+ pub fn is_empty(&self) -> bool {
+ self.0.len() == 0
+ }
#[cfg(test)]
pub fn get_index(&self, account: &Address) -> Option {
@@ -628,6 +631,9 @@ impl Jail {
pub fn len(&self) -> usize {
self.0.len()
}
+ pub fn is_empty(&self) -> bool {
+ self.0.len() == 0
+ }
pub fn add(&mut self, candidate: Candidate, custody_until: u64, released_at: u64) {
assert!(custody_until <= released_at);
diff --git a/core/src/consensus/stake/distribute.rs b/core/src/consensus/stake/distribute.rs
index 1c5dd55ea0..d76d13bac6 100644
--- a/core/src/consensus/stake/distribute.rs
+++ b/core/src/consensus/stake/distribute.rs
@@ -19,7 +19,10 @@ use std::collections::hash_map;
use std::collections::HashMap;
use std::convert::TryFrom;
-pub fn fee_distribute(total_min_fee: u64, stakes: &HashMap) -> FeeDistributeIter {
+pub fn fee_distribute(
+ total_min_fee: u64,
+ stakes: &HashMap,
+) -> FeeDistributeIter {
FeeDistributeIter {
total_stakes: stakes.values().sum(),
total_min_fee,
diff --git a/core/src/consensus/stake/mod.rs b/core/src/consensus/stake/mod.rs
index ee7601b4ee..4c7a636f06 100644
--- a/core/src/consensus/stake/mod.rs
+++ b/core/src/consensus/stake/mod.rs
@@ -32,8 +32,8 @@ use std::collections::btree_map::BTreeMap;
use std::collections::HashMap;
use std::sync::{Arc, Weak};
-pub use self::action_data::{Banned, Validator, Validators};
-use self::action_data::{Candidates, Delegation, IntermediateRewards, Jail, ReleaseResult, StakeAccount, Stakeholders};
+pub use self::action_data::{Banned, Candidates, Jail, Validator, Validators};
+use self::action_data::{Delegation, IntermediateRewards, ReleaseResult, StakeAccount, Stakeholders};
pub use self::actions::Action;
pub use self::distribute::fee_distribute;
use super::ValidatorSet;
diff --git a/core/src/consensus/tendermint/engine.rs b/core/src/consensus/tendermint/engine.rs
index 6e15d3b5b9..b0b14505c6 100644
--- a/core/src/consensus/tendermint/engine.rs
+++ b/core/src/consensus/tendermint/engine.rs
@@ -53,10 +53,6 @@ struct WorkInfo {
}
impl ConsensusEngine for Tendermint {
- fn name(&self) -> &str {
- "Tendermint"
- }
-
fn machine(&self) -> &CodeChainMachine {
&self.machine.as_ref()
}
@@ -137,7 +133,6 @@ impl ConsensusEngine for Tendermint {
self.inner.send(worker::Event::OnTimeout(token)).unwrap();
}
- fn stop(&self) {}
fn on_close_block(
&self,
diff --git a/core/src/consensus/tendermint/mod.rs b/core/src/consensus/tendermint/mod.rs
index 87c6d37b11..4523840ef6 100644
--- a/core/src/consensus/tendermint/mod.rs
+++ b/core/src/consensus/tendermint/mod.rs
@@ -29,7 +29,7 @@ use self::chain_notify::TendermintChainNotify;
pub use self::message::{ConsensusMessage, VoteOn, VoteStep};
pub use self::params::{TendermintParams, TimeGapParams, TimeoutParams};
pub use self::types::{Height, Step, View};
-use super::{stake, ValidatorSet};
+pub use super::{stake, ValidatorSet};
use crate::client::ConsensusClient;
use crate::codechain_machine::CodeChainMachine;
use crate::ChainNotify;
@@ -124,16 +124,17 @@ const SEAL_FIELDS: usize = 4;
#[cfg(test)]
mod tests {
use ccrypto::blake256;
- use ckey::Address;
+ use ckey::{public_to_address, sign_schnorr, Address, KeyPair, Private};
use ctypes::{CommonParams, Header};
use primitives::Bytes;
+ use std::str::FromStr;
use super::super::BitSet;
use super::message::VoteStep;
use crate::account_provider::AccountProvider;
use crate::block::{ClosedBlock, OpenBlock};
use crate::client::TestBlockChainClient;
- use crate::consensus::{CodeChainEngine, EngineError, Seal};
+ use crate::consensus::{CodeChainEngine, Seal};
use crate::error::BlockError;
use crate::error::Error;
use crate::scheme::Scheme;
@@ -177,15 +178,44 @@ mod tests {
}
#[test]
- fn has_valid_metadata() {
- use std::time::Duration;
- let engine = Scheme::new_test_tendermint().engine;
- let time_gap_params = TimeGapParams {
- allowed_past_gap: Duration::from_millis(30000),
- allowed_future_gap: Duration::from_millis(5000),
+ fn serialize_deserialize_test() {
+ let key_pair = {
+ let serialized_priv_key = "ede1d4ccb4ec9a8bbbae9a13db3f4a7b56ea04189be86ac3a6a439d9a0a1addd";
+ let private_key = Private::from_str(&serialized_priv_key).unwrap();
+ KeyPair::from_private(private_key).unwrap()
+ };
+
+ let mut header = Header::default();
+ header.set_number(4);
+ header.set_author(public_to_address(key_pair.public()));
+
+ let precommit_bitset = {
+ let mut bitset = BitSet::new();
+ bitset.set(2);
+ bitset
};
- engine.register_time_gap_config_to_worker(time_gap_params);
- assert!(!engine.name().is_empty());
+ let signature = {
+ let height = 3;
+ let view = 0;
+ let step = Step::Precommit;
+ let vote_on = VoteOn {
+ step: VoteStep::new(height, view, step),
+ block_hash: Some(*header.parent_hash()),
+ };
+ sign_schnorr(key_pair.private(), &vote_on.hash()).unwrap()
+ };
+ let seal = Seal::Tendermint {
+ prev_view: 0,
+ cur_view: 0,
+ precommits: vec![signature],
+ precommit_bitset,
+ };
+ header.set_seal(seal.seal_fields().unwrap());
+
+ let encoded = rlp::encode(&header);
+ let decoded: Header = rlp::decode(&encoded).unwrap();
+
+ assert_eq!(header.hash(), decoded.hash());
}
#[test]
@@ -249,83 +279,4 @@ mod tests {
println!(".....");
assert!(engine.verify_block_external(&header).is_err());
}
-
- #[test]
- #[ignore] // FIXME
- fn seal_signatures_checking() {
- let (spec, tap, c) = setup();
- let engine = spec.engine;
-
- let validator0 = insert_and_unlock(&tap, "0");
- let validator1 = insert_and_unlock(&tap, "1");
- let validator2 = insert_and_unlock(&tap, "2");
- let validator3 = insert_and_unlock(&tap, "3");
-
- let block1_hash = c.add_block_with_author(Some(validator1), 1, 1);
-
- let mut header = Header::default();
- header.set_number(2);
- let proposer = validator2;
- header.set_author(proposer);
- header.set_parent_hash(block1_hash);
-
- let vote_info = VoteOn {
- step: VoteStep::new(1, 0, Step::Precommit),
- block_hash: Some(*header.parent_hash()),
- };
- let signature2 = tap.get_account(&proposer, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap();
-
- let seal = Seal::Tendermint {
- prev_view: 0,
- cur_view: 0,
- precommits: vec![signature2],
- precommit_bitset: BitSet::new_with_indices(&[2]),
- }
- .seal_fields()
- .unwrap();
- header.set_seal(seal);
-
- // One good signature is not enough.
- match engine.verify_block_external(&header) {
- Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {}
- _ => panic!(),
- }
-
- let voter = validator3;
- let signature3 = tap.get_account(&voter, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap();
- let voter = validator0;
- let signature0 = tap.get_account(&voter, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap();
-
- let seal = Seal::Tendermint {
- prev_view: 0,
- cur_view: 0,
- precommits: vec![signature0, signature2, signature3],
- precommit_bitset: BitSet::new_with_indices(&[0, 2, 3]),
- }
- .seal_fields()
- .unwrap();
- header.set_seal(seal);
-
- assert!(engine.verify_block_external(&header).is_ok());
-
- let bad_voter = insert_and_unlock(&tap, "101");
- let bad_signature = tap.get_account(&bad_voter, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap();
-
- let seal = Seal::Tendermint {
- prev_view: 0,
- cur_view: 0,
- precommits: vec![signature0, signature2, bad_signature],
- precommit_bitset: BitSet::new_with_indices(&[0, 2, 3]),
- }
- .seal_fields()
- .unwrap();
- header.set_seal(seal);
-
- // Two good and one bad signature.
- match engine.verify_block_external(&header) {
- Err(Error::Engine(EngineError::BlockNotAuthorized(_))) => {}
- _ => panic!(),
- };
- engine.stop();
- }
}
diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs
index 763250873e..fb399d075e 100644
--- a/core/src/consensus/tendermint/worker.rs
+++ b/core/src/consensus/tendermint/worker.rs
@@ -956,6 +956,7 @@ impl Worker {
if !self.votes.is_old_or_known(&message) {
if let Err(double_vote) = self.votes.collect(message) {
cerror!(ENGINE, "Double vote found on_commit_message: {:?}", double_vote);
+ self.report_double_vote(&double_vote);
}
}
}
@@ -1432,9 +1433,9 @@ impl Worker {
self.votes_received.set(vote_index);
}
- if let Err(double) = self.votes.collect(message.clone()) {
- cerror!(ENGINE, "Double vote found {:?}", double);
- self.report_double_vote(&double);
+ if let Err(double_vote) = self.votes.collect(message.clone()) {
+ cerror!(ENGINE, "Double vote found {:?}", double_vote);
+ self.report_double_vote(&double_vote);
return Err(EngineError::DoubleVote(sender))
}
ctrace!(ENGINE, "Handling a valid {:?} from {}.", message, sender);
@@ -1821,9 +1822,9 @@ impl Worker {
);
}
- if let Err(double) = self.votes.collect(message) {
- cerror!(ENGINE, "Double Vote found {:?}", double);
- self.report_double_vote(&double);
+ if let Err(double_vote) = self.votes.collect(message) {
+ cerror!(ENGINE, "Double Vote found {:?}", double_vote);
+ self.report_double_vote(&double_vote);
return None
}
}
@@ -2162,6 +2163,7 @@ impl Worker {
if !self.votes.is_old_or_known(&vote) {
if let Err(double_vote) = self.votes.collect(vote) {
cerror!(ENGINE, "Double vote found on_commit_message: {:?}", double_vote);
+ self.report_double_vote(&double_vote);
}
}
}
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 9e378dca47..f748b5d7df 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -82,14 +82,15 @@ mod tests;
pub use crate::account_provider::{AccountProvider, Error as AccountProviderError};
pub use crate::block::Block;
pub use crate::client::{
- AccountData, AssetClient, BlockChainClient, BlockChainTrait, ChainNotify, Client, ClientConfig, DatabaseClient,
- EngineClient, EngineInfo, ExecuteClient, ImportBlock, MiningBlockChainClient, Shard, StateInfo, TermInfo,
- TestBlockChainClient, TextClient,
+ AccountData, AssetClient, BlockChainClient, BlockChainTrait, ChainNotify, Client, ClientConfig, ConsensusClient,
+ DatabaseClient, EngineClient, EngineInfo, ExecuteClient, ImportBlock, MiningBlockChainClient, Shard, StateInfo,
+ TermInfo, TestBlockChainClient, TextClient,
};
+pub use crate::consensus::stake;
pub use crate::consensus::{EngineType, TimeGapParams};
pub use crate::db::{COL_STATE, NUM_COLUMNS};
pub use crate::error::{BlockImportError, Error, ImportError};
-pub use crate::miner::{MemPoolFees, Miner, MinerOptions, MinerService, Stratum, StratumConfig, StratumError};
+pub use crate::miner::{MemPoolMinFees, Miner, MinerOptions, MinerService, Stratum, StratumConfig, StratumError};
pub use crate::peer_db::PeerDb;
pub use crate::scheme::Scheme;
pub use crate::service::ClientService;
diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs
index c7aca0cb99..bf2a4f0d1e 100644
--- a/core/src/miner/mem_pool.rs
+++ b/core/src/miner/mem_pool.rs
@@ -16,8 +16,8 @@
use super::backup;
use super::mem_pool_types::{
- AccountDetails, CurrentQueue, FutureQueue, MemPoolFees, MemPoolInput, MemPoolItem, MemPoolStatus, PoolingInstant,
- QueueTag, TransactionOrder, TransactionOrderWithTag, TxOrigin, TxTimelock,
+ AccountDetails, CurrentQueue, FutureQueue, MemPoolInput, MemPoolItem, MemPoolMinFees, MemPoolStatus,
+ PoolingInstant, QueueTag, TransactionOrder, TransactionOrderWithTag, TxOrigin, TxTimelock,
};
use super::TransactionImportResult;
use crate::client::{AccountData, BlockChainTrait};
@@ -74,7 +74,7 @@ impl From for Error {
pub struct MemPool {
/// Fee threshold for transactions that can be imported to this pool
- minimum_fees: MemPoolFees,
+ minimum_fees: MemPoolMinFees,
/// A value which is used to check whether a new transaciton can replace a transaction in the memory pool with the same signer and seq.
/// If the fee of the new transaction is `new_fee` and the fee of the transaction in the memory pool is `old_fee`,
/// then `new_fee > old_fee + old_fee >> mem_pool_fee_bump_shift` should be satisfied to replace.
@@ -119,7 +119,7 @@ impl MemPool {
memory_limit: usize,
fee_bump_shift: usize,
db: Arc,
- minimum_fees: MemPoolFees,
+ minimum_fees: MemPoolMinFees,
) -> Self {
MemPool {
minimum_fees,
@@ -868,17 +868,6 @@ impl MemPool {
Ok(())
}
- /// Removes all elements (in any state) from the pool
- #[allow(dead_code)]
- pub fn clear(&mut self) {
- self.current.clear();
- self.future.clear();
- self.by_signer_public.clear();
- self.by_hash.clear();
- self.first_seqs.clear();
- self.next_seqs.clear();
- }
-
/// Returns top transactions whose timestamp are in the given range from the pool ordered by priority.
// FIXME: current_timestamp should be `u64`, not `Option`.
// FIXME: if range_contains becomes stable, use range.contains instead of inequality.
@@ -1669,7 +1658,7 @@ pub mod test {
let test_client = TestBlockChainClient::new();
// Set the pay transaction minimum fee
- let fees = MemPoolFees::create_from_options(
+ let fees = MemPoolMinFees::create_from_options(
Some(150),
None,
None,
@@ -1724,7 +1713,7 @@ pub mod test {
fn external_transactions_whose_fees_are_under_the_mem_pool_min_fee_are_rejected() {
let test_client = TestBlockChainClient::new();
// Set the pay transaction minimum fee
- let fees = MemPoolFees::create_from_options(
+ let fees = MemPoolMinFees::create_from_options(
Some(150),
None,
None,
diff --git a/core/src/miner/mem_pool_types.rs b/core/src/miner/mem_pool_types.rs
index bc1eb7094f..26a85eb4f6 100644
--- a/core/src/miner/mem_pool_types.rs
+++ b/core/src/miner/mem_pool_types.rs
@@ -440,24 +440,24 @@ pub struct AccountDetails {
#[derive(Default, Clone, Copy, Debug, PartialEq)]
/// Minimum fee thresholds defined not by network but by Mempool
-pub struct MemPoolFees {
- min_pay_transaction_cost: u64,
- min_set_regular_key_transaction_cost: u64,
- min_create_shard_transaction_cost: u64,
- min_set_shard_owners_transaction_cost: u64,
- min_set_shard_users_transaction_cost: u64,
- min_wrap_ccc_transaction_cost: u64,
- min_custom_transaction_cost: u64,
- min_store_transaction_cost: u64,
- min_remove_transaction_cost: u64,
- min_asset_mint_cost: u64,
- min_asset_transfer_cost: u64,
- min_asset_scheme_change_cost: u64,
- min_asset_supply_increase_cost: u64,
- min_asset_unwrap_ccc_cost: u64,
+pub struct MemPoolMinFees {
+ pub min_pay_transaction_cost: u64,
+ pub min_set_regular_key_transaction_cost: u64,
+ pub min_create_shard_transaction_cost: u64,
+ pub min_set_shard_owners_transaction_cost: u64,
+ pub min_set_shard_users_transaction_cost: u64,
+ pub min_wrap_ccc_transaction_cost: u64,
+ pub min_custom_transaction_cost: u64,
+ pub min_store_transaction_cost: u64,
+ pub min_remove_transaction_cost: u64,
+ pub min_asset_mint_cost: u64,
+ pub min_asset_transfer_cost: u64,
+ pub min_asset_scheme_change_cost: u64,
+ pub min_asset_supply_increase_cost: u64,
+ pub min_asset_unwrap_ccc_cost: u64,
}
-impl MemPoolFees {
+impl MemPoolMinFees {
#[allow(clippy::too_many_arguments)]
pub fn create_from_options(
min_pay_cost_option: Option,
@@ -475,7 +475,7 @@ impl MemPoolFees {
min_asset_supply_increase_cost_option: Option,
min_asset_unwrap_ccc_cost_option: Option,
) -> Self {
- MemPoolFees {
+ MemPoolMinFees {
min_pay_transaction_cost: min_pay_cost_option.unwrap_or_default(),
min_set_regular_key_transaction_cost: min_set_regular_key_cost_option.unwrap_or_default(),
min_create_shard_transaction_cost: min_create_shard_cost_option.unwrap_or_default(),
diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs
index cc865d20b8..51a5ff5e70 100644
--- a/core/src/miner/miner.rs
+++ b/core/src/miner/miner.rs
@@ -15,7 +15,7 @@
// along with this program. If not, see .
use super::mem_pool::{Error as MemPoolError, MemPool};
-pub use super::mem_pool_types::MemPoolFees;
+pub use super::mem_pool_types::MemPoolMinFees;
use super::mem_pool_types::{MemPoolInput, TxOrigin, TxTimelock};
use super::sealing_queue::SealingQueue;
use super::work_notify::{NotifyWork, WorkPoster};
@@ -46,7 +46,7 @@ use std::iter::once;
use std::ops::Range;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
-use std::time::{Duration, Instant};
+use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
/// Configures the behaviour of the miner.
#[derive(Debug, PartialEq)]
@@ -78,7 +78,7 @@ pub struct MinerOptions {
/// How many historical work packages can we store before running out?
pub work_queue_size: usize,
/// Minimum fees configured by the machine.
- pub mem_pool_fees: MemPoolFees,
+ pub mem_pool_min_fees: MemPoolMinFees,
}
impl Default for MinerOptions {
@@ -96,7 +96,7 @@ impl Default for MinerOptions {
mem_pool_fee_bump_shift: 3,
allow_create_shard: false,
work_queue_size: 20,
- mem_pool_fees: Default::default(),
+ mem_pool_min_fees: Default::default(),
}
}
}
@@ -124,7 +124,7 @@ pub struct Miner {
sealing_enabled: AtomicBool,
- accounts: Option>,
+ accounts: Arc,
notifiers: Notifiers,
malicious_users: Users,
immune_users: Users,
@@ -266,20 +266,20 @@ impl Miner {
pub fn new(
options: MinerOptions,
scheme: &Scheme,
- accounts: Option>,
+ accounts: Arc,
db: Arc,
) -> Arc {
Arc::new(Self::new_raw(options, scheme, accounts, db))
}
- pub fn with_scheme(scheme: &Scheme, db: Arc) -> Self {
- Self::new_raw(Default::default(), scheme, None, db)
+ pub fn with_scheme_for_test(scheme: &Scheme, db: Arc) -> Self {
+ Self::new_raw(Default::default(), scheme, AccountProvider::transient_provider(), db)
}
fn new_raw(
options: MinerOptions,
scheme: &Scheme,
- accounts: Option>,
+ accounts: Arc,
db: Arc,
) -> Self {
let mem_limit = options.mem_pool_memory_limit.unwrap_or_else(usize::max_value);
@@ -288,7 +288,7 @@ impl Miner {
mem_limit,
options.mem_pool_fee_bump_shift,
db,
- options.mem_pool_fees,
+ options.mem_pool_min_fees,
)));
let notifiers: Vec> = if options.new_work_notify.is_empty() {
@@ -401,15 +401,11 @@ impl Miner {
self.immune_users.insert(signer_address);
}
- let origin = self
- .accounts
- .as_ref()
- .and_then(|accounts| match accounts.has_public(&signer_public) {
- Ok(true) => Some(TxOrigin::Local),
- Ok(false) => None,
- Err(_) => None,
- })
- .unwrap_or(default_origin);
+ let origin = if self.accounts.has_public(&signer_public).unwrap_or_default() {
+ TxOrigin::Local
+ } else {
+ default_origin
+ };
if self.malicious_users.contains(&signer_address) {
// FIXME: just to skip, think about another way.
@@ -437,7 +433,7 @@ impl Miner {
}
_ => {}
}
- cdebug!(MINER, "Rejected transaction {:?} with invalid signature: {:?}", hash, e);
+ cdebug!(MINER, "Rejected transaction {:?} with error {:?}", hash, e);
e
})?;
@@ -661,7 +657,7 @@ impl Miner {
// Check whether transaction type is allowed for sender
let result =
self.engine.machine().verify_transaction(&tx, open_block.header(), chain, true).and_then(|_| {
- open_block.push_transaction(tx, None, chain, parent_header.number(), parent_header.timestamp())
+ open_block.push_transaction(tx, chain, parent_header.number(), parent_header.timestamp())
});
match result {
@@ -777,7 +773,7 @@ impl Miner {
self.engine.proposal_generated(&sealed);
}
- chain.import_sealed_block(&sealed).is_ok()
+ chain.import_generated_block(&sealed).is_ok()
}
/// Are we allowed to do a non-mandatory reseal?
@@ -834,24 +830,21 @@ impl MinerService for Miner {
self.params.apply(|params| params.author = address);
if self.engine_type().need_signer_key() && self.engine.seals_internally().is_some() {
- if let Some(ref ap) = self.accounts {
- ctrace!(MINER, "Set author to {:?}", address);
- // Sign test message
- ap.get_unlocked_account(&address)?.sign(&Default::default())?;
- // Limit the scope of the locks.
- {
- let mut sealing_work = self.sealing_work.lock();
- sealing_work.enabled = true;
- }
- self.engine.set_signer(ap.clone(), address);
- Ok(())
- } else {
- cwarn!(MINER, "No account provider");
- Err(AccountProviderError::NotFound)
+ ctrace!(MINER, "Set author to {:?}", address);
+ // Sign test message
+ self.accounts.get_unlocked_account(&address)?.sign(&Default::default())?;
+ // Limit the scope of the locks.
+ {
+ let mut sealing_work = self.sealing_work.lock();
+ sealing_work.enabled = true;
}
- } else {
- Ok(())
+ self.engine.set_signer(Arc::clone(&self.accounts), address);
}
+ Ok(())
+ }
+
+ fn get_author_address(&self) -> Address {
+ self.params.get().author
}
fn set_extra_data(&self, extra_data: Bytes) {
@@ -998,6 +991,14 @@ impl MinerService for Miner {
}
};
+ if std::env::var("RUN_ON_TEST").is_ok() {
+ let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("There is no time machine.").as_secs();
+ if block.header().timestamp() > now {
+ let delta = block.header().timestamp() - now;
+ std::thread::sleep(std::time::Duration::from_secs(delta));
+ }
+ }
+
match self.engine.seals_internally() {
Some(true) => {
ctrace!(MINER, "update_sealing: engine indicates internal sealing");
@@ -1049,7 +1050,7 @@ impl MinerService for Miner {
result.and_then(|sealed| {
let n = sealed.header().number();
let h = sealed.header().hash();
- chain.import_sealed_block(&sealed)?;
+ chain.import_generated_block(&sealed)?;
cinfo!(MINER, "Submitted block imported OK. #{}: {}", n, h);
Ok(())
})
@@ -1276,7 +1277,7 @@ pub mod test {
fn check_add_transactions_result_idx() {
let db = Arc::new(kvdb_memorydb::create(NUM_COLUMNS.unwrap()));
let scheme = Scheme::new_test();
- let miner = Arc::new(Miner::with_scheme(&scheme, db.clone()));
+ let miner = Arc::new(Miner::with_scheme_for_test(&scheme, db.clone()));
let mut mem_pool = MemPool::with_limits(8192, usize::max_value(), 3, db.clone(), Default::default());
let client = generate_test_client(db, Arc::clone(&miner), &scheme).unwrap();
diff --git a/core/src/miner/mod.rs b/core/src/miner/mod.rs
index 10d37fa3eb..64e69c9210 100644
--- a/core/src/miner/mod.rs
+++ b/core/src/miner/mod.rs
@@ -24,7 +24,7 @@ mod stratum;
mod work_notify;
use self::mem_pool_types::AccountDetails;
-pub use self::mem_pool_types::MemPoolFees;
+pub use self::mem_pool_types::MemPoolMinFees;
pub use self::miner::{AuthoringParams, Miner, MinerOptions};
pub use self::stratum::{Config as StratumConfig, Error as StratumError, Stratum};
use crate::account_provider::{AccountProvider, Error as AccountProviderError};
@@ -58,6 +58,9 @@ pub trait MinerService: Send + Sync {
/// Set the author that we will seal blocks as.
fn set_author(&self, author: Address) -> Result<(), AccountProviderError>;
+ ///Get the address that sealed the block.
+ fn get_author_address(&self) -> Address;
+
/// Set the extra_data that we will seal blocks with.
fn set_extra_data(&self, extra_data: Bytes);
@@ -120,7 +123,7 @@ pub trait MinerService: Send + Sync {
) -> Vec>;
/// Imports own (node owner) transaction to mem pool.
- fn import_own_transaction(
+ fn import_own_transaction(
&self,
chain: &C,
tx: SignedTransaction,
diff --git a/core/src/scheme/scheme.rs b/core/src/scheme/scheme.rs
index e35ec00fb5..7d2f7f4b88 100644
--- a/core/src/scheme/scheme.rs
+++ b/core/src/scheme/scheme.rs
@@ -17,11 +17,10 @@
use super::pod_state::{PodAccounts, PodShards};
use super::seal::Generic as GenericSeal;
use super::Genesis;
-use crate::blockchain::HeaderProvider;
use crate::codechain_machine::CodeChainMachine;
use crate::consensus::{BlakePoW, CodeChainEngine, Cuckoo, NullEngine, SimplePoA, Solo, Tendermint};
use crate::error::{Error, SchemeError};
-use ccrypto::{blake256, BLAKE_NULL_RLP};
+use ccrypto::BLAKE_NULL_RLP;
use cdb::{AsHashDB, HashDB};
use cjson;
use ckey::Address;
@@ -199,19 +198,6 @@ impl Scheme {
Ok(self.initialize_state(db)?)
}
- pub fn check_genesis_common_params(&self, chain: &HP) -> Result<(), Error> {
- let genesis_header = self.genesis_header();
- let genesis_header_hash = genesis_header.hash();
- let header =
- chain.block_header(&genesis_header_hash).ok_or_else(|| Error::Scheme(SchemeError::InvalidCommonParams))?;
- let extra_data = header.extra_data();
- let common_params_hash = blake256(&self.genesis_params().rlp_bytes()).to_vec();
- if extra_data != &common_params_hash {
- return Err(Error::Scheme(SchemeError::InvalidCommonParams))
- }
- Ok(())
- }
-
/// Return the state root for the genesis state, memoising accordingly.
pub fn state_root(&self) -> H256 {
*self.state_root_memo.read()
@@ -291,7 +277,7 @@ impl Scheme {
header.set_number(0);
header.set_author(self.author);
header.set_transactions_root(self.transactions_root);
- header.set_extra_data(blake256(&self.genesis_params().rlp_bytes()).to_vec());
+ header.set_extra_data(self.extra_data.clone());
header.set_state_root(self.state_root());
header.set_score(self.score);
header.set_seal({
@@ -354,21 +340,3 @@ fn load_from(s: cjson::scheme::Scheme) -> Result {
Ok(s)
}
-
-#[cfg(test)]
-mod tests {
- use ccrypto::Blake;
-
- use super::*;
-
- #[test]
- fn extra_data_of_genesis_header_is_hash_of_common_params() {
- let scheme = Scheme::new_test();
- let common_params = scheme.genesis_params();
- let hash_of_common_params = H256::blake(&common_params.rlp_bytes()).to_vec();
-
- let genesis_header = scheme.genesis_header();
- let result = genesis_header.extra_data();
- assert_eq!(&hash_of_common_params, result);
- }
-}
diff --git a/core/src/service.rs b/core/src/service.rs
index cb75c7d7f5..59347bcb66 100644
--- a/core/src/service.rs
+++ b/core/src/service.rs
@@ -20,7 +20,6 @@ use crate::miner::Miner;
use crate::scheme::Scheme;
use crate::BlockId;
use cio::{IoContext, IoHandler, IoHandlerResult, IoService};
-use cnetwork::NodeId;
use ctimer::TimerApi;
use ctypes::BlockHash;
use kvdb::KeyValueDB;
@@ -71,7 +70,7 @@ pub enum ClientIoMessage {
/// A header is ready
HeaderVerified,
/// New transaction RLPs are ready to be imported
- NewTransactions(Vec, NodeId),
+ NewTransactions(Vec),
/// Block generation is required
NewBlockRequired {
parent_block: BlockId,
@@ -96,8 +95,8 @@ impl IoHandler for ClientIoHandler {
ClientIoMessage::HeaderVerified => {
self.client.import_verified_headers();
}
- ClientIoMessage::NewTransactions(transactions, peer_id) => {
- self.client.import_queued_transactions(&transactions, peer_id);
+ ClientIoMessage::NewTransactions(transactions) => {
+ self.client.import_queued_transactions(&transactions);
}
ClientIoMessage::NewBlockRequired {
parent_block,
diff --git a/core/src/tests/helpers.rs b/core/src/tests/helpers.rs
index 348f547bca..57015d63bc 100644
--- a/core/src/tests/helpers.rs
+++ b/core/src/tests/helpers.rs
@@ -15,7 +15,6 @@
// along with this program. If not, see .
use crate::scheme::Scheme;
-use crate::transaction::SignedTransaction;
use cstate::StateDB;
use ctypes::{BlockHash, Header};
use primitives::{Bytes, U256};
@@ -28,18 +27,6 @@ pub fn create_test_block(header: &Header) -> Bytes {
rlp.out()
}
-#[allow(dead_code)]
-pub fn create_test_block_with_data(header: &Header, txs: &[SignedTransaction], uncles: &[Header]) -> Bytes {
- let mut rlp = RlpStream::new_list(3);
- rlp.append(header);
- rlp.begin_list(txs.len());
- for t in txs {
- rlp.append_raw(&rlp::encode(t), 1);
- }
- rlp.append_list(&uncles);
- rlp.out()
-}
-
pub fn get_good_dummy_block() -> Bytes {
let (_, bytes) = get_good_dummy_block_hash();
bytes
diff --git a/core/src/verification/canon_verifier.rs b/core/src/verification/canon_verifier.rs
deleted file mode 100644
index 86adff0411..0000000000
--- a/core/src/verification/canon_verifier.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018-2019 Kodebox, Inc.
-// This file is part of CodeChain.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-use super::verification;
-use super::Verifier;
-use crate::client::BlockChainTrait;
-use crate::consensus::CodeChainEngine;
-use crate::error::Error;
-use ctypes::{CommonParams, Header};
-
-/// A canonial verifier -- this does full verification.
-pub struct CanonVerifier;
-
-impl Verifier for CanonVerifier {
- fn verify_block_family(
- &self,
- block: &[u8],
- header: &Header,
- parent: &Header,
- engine: &dyn CodeChainEngine,
- do_full: Option>,
- common_params: &CommonParams,
- ) -> Result<(), Error> {
- verification::verify_block_family(block, header, parent, engine, do_full, common_params)
- }
-
- fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error> {
- verification::verify_block_final(expected, got)
- }
-
- fn verify_block_external(&self, header: &Header, engine: &dyn CodeChainEngine) -> Result<(), Error> {
- engine.verify_block_external(header)
- }
-}
diff --git a/core/src/verification/mod.rs b/core/src/verification/mod.rs
index a13cb4a00e..dce8ca2e85 100644
--- a/core/src/verification/mod.rs
+++ b/core/src/verification/mod.rs
@@ -14,53 +14,11 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-mod canon_verifier;
-mod noop_verifier;
pub mod queue;
#[cfg_attr(feature = "cargo-clippy", allow(clippy::module_inception))]
mod verification;
mod verifier;
-pub use self::canon_verifier::CanonVerifier;
-pub use self::noop_verifier::NoopVerifier;
pub use self::queue::{BlockQueue, Config as QueueConfig};
pub use self::verification::*;
pub use self::verifier::Verifier;
-
-use crate::client::BlockChainTrait;
-
-/// Verifier type.
-#[derive(Debug, PartialEq, Clone, Copy)]
-pub enum VerifierType {
- /// Verifies block normally.
- Canon,
- /// Verifies block normally, but skips seal verification.
- CanonNoSeal,
- /// Does not verify block at all.
- /// Used in tests.
- Noop,
-}
-
-impl VerifierType {
- /// Check if seal verification is enabled for this verifier type.
- pub fn verifying_seal(self) -> bool {
- match self {
- VerifierType::Canon => true,
- VerifierType::Noop | VerifierType::CanonNoSeal => false,
- }
- }
-}
-
-impl Default for VerifierType {
- fn default() -> Self {
- VerifierType::Canon
- }
-}
-
-/// Create a new verifier based on type.
-pub fn new(v: VerifierType) -> Box> {
- match v {
- VerifierType::Canon | VerifierType::CanonNoSeal => Box::new(CanonVerifier),
- VerifierType::Noop => Box::new(NoopVerifier),
- }
-}
diff --git a/core/src/verification/noop_verifier.rs b/core/src/verification/noop_verifier.rs
deleted file mode 100644
index 9321de701b..0000000000
--- a/core/src/verification/noop_verifier.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018-2019 Kodebox, Inc.
-// This file is part of CodeChain.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-use super::{verification, Verifier};
-use crate::client::BlockChainTrait;
-use crate::consensus::CodeChainEngine;
-use crate::error::Error;
-use ctypes::{CommonParams, Header};
-
-/// A no-op verifier -- this will verify everything it's given immediately.
-pub struct NoopVerifier;
-
-impl Verifier for NoopVerifier {
- fn verify_block_family(
- &self,
- _block: &[u8],
- _: &Header,
- _t: &Header,
- _: &dyn CodeChainEngine,
- _: Option>,
- _common_params: &CommonParams,
- ) -> Result<(), Error> {
- Ok(())
- }
-
- fn verify_block_final(&self, _expected: &Header, _got: &Header) -> Result<(), Error> {
- Ok(())
- }
-
- fn verify_block_external(&self, _header: &Header, _engine: &dyn CodeChainEngine) -> Result<(), Error> {
- Ok(())
- }
-}
diff --git a/core/src/verification/queue/mod.rs b/core/src/verification/queue/mod.rs
index 7f060a4b8a..0b060e0872 100644
--- a/core/src/verification/queue/mod.rs
+++ b/core/src/verification/queue/mod.rs
@@ -68,8 +68,6 @@ pub struct VerificationQueue {
deleting: Arc,
ready_signal: Arc,
total_score: RwLock,
- #[allow(dead_code)]
- empty: Arc,
more_to_verify: Arc,
verifier_handles: Vec>,
max_queue_size: usize,
@@ -135,7 +133,6 @@ impl VerificationQueue {
verified: AtomicUsize::new(0),
},
check_seal,
- empty_mutex: SMutex::new(()),
more_to_verify_mutex: SMutex::new(()),
});
let deleting = Arc::new(AtomicBool::new(false));
@@ -182,7 +179,6 @@ impl VerificationQueue {
deleting,
ready_signal,
total_score: RwLock::new(0.into()),
- empty,
more_to_verify,
verifier_handles,
max_queue_size: cmp::max(config.max_queue_size, MIN_QUEUE_LIMIT),
@@ -511,8 +507,6 @@ struct Verification {
bad: Mutex>,
sizes: Sizes,
check_seal: bool,
- #[allow(dead_code)]
- empty_mutex: SMutex<()>,
more_to_verify_mutex: SMutex<()>,
}
diff --git a/core/src/verification/verifier.rs b/core/src/verification/verifier.rs
index 7b032da593..4fcb058bbe 100644
--- a/core/src/verification/verifier.rs
+++ b/core/src/verification/verifier.rs
@@ -19,13 +19,26 @@ use crate::client::BlockChainTrait;
use crate::consensus::CodeChainEngine;
use crate::error::Error;
use ctypes::{CommonParams, Header};
+use std::marker::PhantomData;
/// Should be used to verify blocks.
-pub trait Verifier: Send + Sync
+pub struct Verifier
where
C: BlockChainTrait, {
+ phantom: PhantomData,
+}
+
+impl Verifier {
+ pub fn new() -> Self {
+ Self {
+ phantom: Default::default(),
+ }
+ }
+}
+
+impl Verifier {
/// Verify a block relative to its parent and uncles.
- fn verify_block_family(
+ pub fn verify_block_family(
&self,
block: &[u8],
header: &Header,
@@ -33,10 +46,17 @@ where
engine: &dyn CodeChainEngine,
do_full: Option>,
common_params: &CommonParams,
- ) -> Result<(), Error>;
+ ) -> Result<(), Error> {
+ verification::verify_block_family(block, header, parent, engine, do_full, common_params)
+ }
/// Do a final verification check for an enacted header vs its expected counterpart.
- fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error>;
+ pub fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error> {
+ verification::verify_block_final(expected, got)
+ }
+
/// Verify a block, inspecting external state.
- fn verify_block_external(&self, header: &Header, engine: &dyn CodeChainEngine) -> Result<(), Error>;
+ pub fn verify_block_external(&self, header: &Header, engine: &dyn CodeChainEngine) -> Result<(), Error> {
+ engine.verify_block_external(header)
+ }
}
diff --git a/discovery/Cargo.toml b/discovery/Cargo.toml
index f04144ecce..d5f30532f2 100644
--- a/discovery/Cargo.toml
+++ b/discovery/Cargo.toml
@@ -5,14 +5,14 @@ authors = ["CodeChain Team
"]
edition = "2018"
[dependencies]
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
codechain-key = { path = "../key" }
codechain-logger = { path = "../util/logger" }
codechain-network = { path = "../network" }
codechain-timer = { path = "../util/timer" }
log = "0.4.6"
never-type = "0.1.0"
-parking_lot = "0.6.0"
+parking_lot = "0.11.0"
primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" }
rand = "0.6.1"
rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.4" }
diff --git a/key/Cargo.toml b/key/Cargo.toml
index 8a3b6cadad..5c59bc36c1 100644
--- a/key/Cargo.toml
+++ b/key/Cargo.toml
@@ -10,9 +10,9 @@ rustc-hex = "1.0"
rustc-serialize = "0.3"
lazy_static = "1.2"
bech32 = "0.2.2"
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
never-type = "0.1.0"
-parking_lot = "0.6.0"
+parking_lot = "0.11.0"
primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" }
rand_xorshift = "0.1.0"
rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.4" }
diff --git a/keystore/Cargo.toml b/keystore/Cargo.toml
index 8c091d432a..aeb8e45751 100644
--- a/keystore/Cargo.toml
+++ b/keystore/Cargo.toml
@@ -16,8 +16,8 @@ serde_json = "1.0"
serde_derive = "1.0"
rustc-hex = "1.0"
time = "0.1.34"
-parking_lot = "0.6.0"
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
+parking_lot = "0.11.0"
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
smallvec = "0.4"
tempdir = "0.3"
diff --git a/keystore/src/account/decrypted_account.rs b/keystore/src/account/decrypted_account.rs
index d9b4ce08ec..6169da3bd4 100644
--- a/keystore/src/account/decrypted_account.rs
+++ b/keystore/src/account/decrypted_account.rs
@@ -19,6 +19,7 @@ use ckey::{
};
/// An opaque wrapper for secret.
+#[derive(Clone)]
pub struct DecryptedAccount {
secret: Secret,
}
diff --git a/network/Cargo.toml b/network/Cargo.toml
index c3c89e7502..a11a8d966a 100644
--- a/network/Cargo.toml
+++ b/network/Cargo.toml
@@ -5,7 +5,7 @@ authors = ["CodeChain Team "]
edition = "2018"
[dependencies]
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
codechain-io = { path = "../util/io" }
codechain-key = { path = "../key" }
codechain-logger = { path = "../util/logger" }
@@ -18,7 +18,7 @@ log = "0.4.6"
kvdb = "0.1"
mio = "0.6.16"
never-type = "0.1.0"
-parking_lot = "0.6.0"
+parking_lot = "0.11.0"
rand = "0.6.1"
rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.4" }
rlp_derive = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.2" }
diff --git a/network/src/p2p/connection/mod.rs b/network/src/p2p/connection/mod.rs
index edacbc470f..4be1cc72e5 100644
--- a/network/src/p2p/connection/mod.rs
+++ b/network/src/p2p/connection/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2019 Kodebox, Inc.
+// Copyright 2019-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -19,7 +19,7 @@ mod incoming;
mod message;
mod outgoing;
-use ccrypto::aes::SymmetricCipherError;
+use ccrypto::error::SymmError;
use rlp::DecoderError;
use std::fmt;
use std::io;
@@ -36,7 +36,7 @@ use super::stream::Error as P2pStreamError;
#[derive(Debug)]
pub enum Error {
- SymmetricCipher(SymmetricCipherError),
+ SymmetricCipher(SymmError),
IoError(io::Error),
Decoder(DecoderError),
InvalidSign,
@@ -78,8 +78,8 @@ impl From for Error {
}
}
-impl From for Error {
- fn from(err: SymmetricCipherError) -> Self {
+impl From for Error {
+ fn from(err: SymmError) -> Self {
Error::SymmetricCipher(err)
}
}
diff --git a/network/src/p2p/handler.rs b/network/src/p2p/handler.rs
index 4a1498ff16..1f12b11749 100644
--- a/network/src/p2p/handler.rs
+++ b/network/src/p2p/handler.rs
@@ -1,4 +1,4 @@
-// Copyright 2018-2019 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -20,10 +20,11 @@ use super::connection::{
use super::listener::Listener;
use super::{NegotiationMessage, NetworkMessage};
use crate::client::Client;
+use crate::p2p::connection::Error as P2PConnectionError;
use crate::session::Session;
use crate::stream::Stream;
use crate::{FiltersControl, NodeId, RoutingTable, SocketAddr};
-use ccrypto::aes::SymmetricCipherError;
+use ccrypto::error::SymmError;
use cio::{IoChannel, IoContext, IoHandler, IoHandlerResult, IoManager, StreamToken, TimerToken};
use ckey::NetworkId;
use finally_block::finally;
@@ -242,7 +243,7 @@ impl Handler {
let mut result = HashMap::with_capacity(network_usage_in_10_seconds.len());
let now = Instant::now();
for (name, times) in &mut *network_usage_in_10_seconds {
- remove_outdated_network_usage(times, &now);
+ remove_outdated_network_usage(times, now);
let total = times.iter().map(|(_, usage)| usage).sum();
if total != 0 {
result.insert(name.clone(), total);
@@ -662,7 +663,13 @@ impl IoHandler for Handler {
io.update_registration(stream_token);
}
});
- match con.receive()? {
+ let received = con.receive();
+ if let Err(P2PConnectionError::IoError(ioerr)) = &received {
+ if ioerr.kind() == std::io::ErrorKind::ConnectionAborted {
+ io.deregister_stream(stream_token);
+ }
+ };
+ match received? {
Some(NetworkMessage::Extension(msg)) => {
let remote_node_id = *self.remote_node_ids.read().get(&stream_token).unwrap_or_else(|| {
unreachable!("Node id for {}:{} must exist", stream_token, con.peer_addr())
@@ -731,7 +738,13 @@ impl IoHandler for Handler {
io.update_registration(stream_token);
}
});
- match con.receive()? {
+ let received = con.receive();
+ if let Err(P2PConnectionError::IoError(ioerr)) = &received {
+ if ioerr.kind() == std::io::ErrorKind::ConnectionAborted {
+ io.deregister_stream(stream_token);
+ }
+ };
+ match received? {
Some(NetworkMessage::Extension(msg)) => {
let remote_node_id = *self.remote_node_ids.read().get(&stream_token).unwrap_or_else(|| {
unreachable!("Node id for {}:{} must exist", stream_token, con.peer_addr())
@@ -776,7 +789,13 @@ impl IoHandler for Handler {
io.update_registration(stream_token);
}
});
- match con.receive()? {
+ let received = con.receive();
+ if let Err(P2PConnectionError::IoError(ioerr)) = &received {
+ if ioerr.kind() == std::io::ErrorKind::ConnectionAborted {
+ io.deregister_stream(stream_token);
+ }
+ };
+ match received? {
Some(OutgoingMessage::Sync1 {
initiator_pub_key,
network_id,
@@ -871,7 +890,13 @@ impl IoHandler for Handler {
}
});
let from = *con.peer_addr();
- match con.receive()? {
+ let received = con.receive();
+ if let Err(P2PConnectionError::IoError(ioerr)) = &received {
+ if ioerr.kind() == std::io::ErrorKind::ConnectionAborted {
+ io.deregister_stream(stream_token);
+ }
+ };
+ match received? {
Some(IncomingMessage::Ack {
recipient_pub_key,
encrypted_nonce,
@@ -908,32 +933,56 @@ impl IoHandler for Handler {
Ok(())
}
- fn stream_writable(&self, _io: &IoContext, stream: StreamToken) -> IoHandlerResult<()> {
+ fn stream_writable(&self, io: &IoContext, stream: StreamToken) -> IoHandlerResult<()> {
match stream {
FIRST_INBOUND..=LAST_INBOUND => {
if let Some(con) = self.inbound_connections.write().get_mut(&stream) {
- con.flush()?;
+ let flush_result = con.flush();
+ if let Err(P2PConnectionError::IoError(io_error)) = &flush_result {
+ if io_error.kind() == std::io::ErrorKind::BrokenPipe {
+ io.deregister_stream(stream);
+ }
+ }
+ flush_result?;
} else {
cdebug!(NETWORK, "Invalid inbound token({}) on write", stream);
}
}
FIRST_OUTBOUND..=LAST_OUTBOUND => {
if let Some(con) = self.outbound_connections.write().get_mut(&stream) {
- con.flush()?;
+ let flush_result = con.flush();
+ if let Err(P2PConnectionError::IoError(io_error)) = &flush_result {
+ if io_error.kind() == std::io::ErrorKind::BrokenPipe {
+ io.deregister_stream(stream);
+ }
+ }
+ flush_result?;
} else {
cdebug!(NETWORK, "Invalid outbound token({}) on write", stream);
}
}
FIRST_INCOMING..=LAST_INCOMING => {
if let Some(con) = self.incoming_connections.write().get_mut(&stream) {
- con.flush()?;
+ let flush_result = con.flush();
+ if let Err(P2PConnectionError::IoError(io_error)) = &flush_result {
+ if io_error.kind() == std::io::ErrorKind::BrokenPipe {
+ io.deregister_stream(stream);
+ }
+ }
+ flush_result?;
} else {
cdebug!(NETWORK, "Invalid incoming token({}) on write", stream);
}
}
FIRST_OUTGOING..=LAST_OUTGOING => {
if let Some(con) = self.outgoing_connections.write().get_mut(&stream) {
- con.flush()?;
+ let flush_result = con.flush();
+ if let Err(P2PConnectionError::IoError(io_error)) = &flush_result {
+ if io_error.kind() == std::io::ErrorKind::BrokenPipe {
+ io.deregister_stream(stream);
+ }
+ }
+ flush_result?;
} else {
cdebug!(NETWORK, "Invalid outgoing token({}) on write", stream);
}
@@ -1155,8 +1204,8 @@ impl IoHandler for Handler {
}
}
-impl From for Error {
- fn from(err: SymmetricCipherError) -> Self {
+impl From for Error {
+ fn from(err: SymmError) -> Self {
Error::SymmetricCipher(err)
}
}
@@ -1186,7 +1235,7 @@ pub enum Message {
#[derive(Debug)]
enum Error {
InvalidNode(NodeId),
- SymmetricCipher(SymmetricCipherError),
+ SymmetricCipher(SymmError),
}
impl ::std::fmt::Display for Error {
@@ -1198,9 +1247,9 @@ impl ::std::fmt::Display for Error {
}
}
-fn remove_outdated_network_usage(usage_per_extension: &mut VecDeque<(Instant, usize)>, now: &Instant) {
+fn remove_outdated_network_usage(usage_per_extension: &mut VecDeque<(Instant, usize)>, now: Instant) {
while let Some((time, size)) = usage_per_extension.pop_front() {
- if *now < time {
+ if now < time {
usage_per_extension.push_front((time, size));
break
}
@@ -1209,6 +1258,6 @@ fn remove_outdated_network_usage(usage_per_extension: &mut VecDeque<(Instant, us
fn insert_network_usage(usage_per_extension: &mut VecDeque<(Instant, usize)>, network_message_size: usize) {
let now = Instant::now();
- remove_outdated_network_usage(usage_per_extension, &now);
+ remove_outdated_network_usage(usage_per_extension, now);
usage_per_extension.push_back((now + Duration::from_secs(10), network_message_size));
}
diff --git a/network/src/p2p/message/extension.rs b/network/src/p2p/message/extension.rs
index bb74bc98ce..5d3d7e0fce 100644
--- a/network/src/p2p/message/extension.rs
+++ b/network/src/p2p/message/extension.rs
@@ -1,4 +1,4 @@
-// Copyright 2018-2019 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -17,7 +17,8 @@
use super::ENCRYPTED_ID;
use super::UNENCRYPTED_ID;
use crate::session::Session;
-use ccrypto::aes::{self, SymmetricCipherError};
+use ccrypto::aes;
+use ccrypto::error::SymmError;
use primitives::Bytes;
use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
use std::sync::Arc;
@@ -47,7 +48,7 @@ impl Message {
extension_name: String,
unencrypted_data: &[u8],
session: &Session,
- ) -> Result {
+ ) -> Result {
let encrypted = aes::encrypt(unencrypted_data, session.secret(), &session.nonce())?;
Ok(Self::encrypted(extension_name, encrypted))
}
@@ -73,7 +74,7 @@ impl Message {
}
}
- pub fn unencrypted_data(&self, session: &Session) -> Result, SymmetricCipherError> {
+ pub fn unencrypted_data(&self, session: &Session) -> Result, SymmError> {
match self {
Message::Encrypted {
encrypted,
@@ -124,7 +125,7 @@ impl Decodable for Message {
let item_count = rlp.item_count()?;
if item_count != 3 {
return Err(DecoderError::RlpInvalidLength {
- expected: 5,
+ expected: 3,
got: item_count,
})
}
diff --git a/network/src/routing_table.rs b/network/src/routing_table.rs
index dd8ed4d1b1..cb33539f57 100644
--- a/network/src/routing_table.rs
+++ b/network/src/routing_table.rs
@@ -1,4 +1,4 @@
-// Copyright 2018-2019 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,8 @@
use crate::session::{Nonce, Session};
use crate::SocketAddr;
-use ccrypto::aes::{self, SymmetricCipherError};
+use ccrypto::aes;
+use ccrypto::error::SymmError;
use ckey::{exchange, Generator, KeyPair, Public, Random, Secret};
use parking_lot::{Mutex, RwLock};
use primitives::Bytes;
@@ -506,8 +507,7 @@ impl RoutingTable {
State::Establishing1(local_key_pair) => {
let shared_secret = exchange(&remote_public, local_key_pair.private())
.map_err(|e| format!("Cannot exchange key: {:?}", e))?;
- let nonce = decrypt_nonce(encrypted_nonce, &shared_secret)
- .map_err(|e| format!("Cannot decrypt nonce: {:?}", e))?;
+ let nonce = decrypt_nonce(encrypted_nonce, &shared_secret)?;
State::Established {
local_key_pair: *local_key_pair,
remote_public,
@@ -529,8 +529,7 @@ impl RoutingTable {
))
}
debug_assert_eq!(*shared_secret, exchange(&remote_public, local_key_pair.private()).unwrap());
- let nonce = decrypt_nonce(encrypted_nonce, &shared_secret)
- .map_err(|e| format!("Cannot decrypt nonce: {:?}", e))?;
+ let nonce = decrypt_nonce(encrypted_nonce, &shared_secret)?;
State::Established {
local_key_pair: *local_key_pair,
remote_public,
@@ -618,19 +617,23 @@ impl RoutingTable {
}
}
-fn decrypt_nonce(encrypted_bytes: &[u8], shared_secret: &Secret) -> Result {
+fn decrypt_nonce(encrypted_bytes: &[u8], shared_secret: &Secret) -> Result {
let iv = 0; // FIXME: Use proper iv
- let unecrypted = aes::decrypt(encrypted_bytes, shared_secret, &iv)?;
+ let unecrypted =
+ aes::decrypt(encrypted_bytes, shared_secret, &iv).map_err(|e| format!("Cannot decrypt nonce: {:?}", e))?;
debug_assert_eq!(std::mem::size_of::(), 16);
if unecrypted.len() != 16 {
- return Err(SymmetricCipherError::InvalidLength) // FIXME
+ return Err(format!(
+ "Cannot decrpyt nonce: 16 length bytes expected but, {} length bytes received",
+ unecrypted.len()
+ )) // FIXME
}
let mut nonce_bytes = [0u8; 16];
nonce_bytes.copy_from_slice(&unecrypted);
Ok(Nonce::from_be_bytes(nonce_bytes))
}
-fn encrypt_nonce(nonce: Nonce, shared_secret: &Secret) -> Result {
+fn encrypt_nonce(nonce: Nonce, shared_secret: &Secret) -> Result {
let iv = 0; // FIXME: Use proper iv
Ok(aes::encrypt(&nonce.to_be_bytes(), shared_secret, &iv)?)
}
diff --git a/network/src/session/session.rs b/network/src/session/session.rs
index 21b4993a3e..1f3967dc06 100644
--- a/network/src/session/session.rs
+++ b/network/src/session/session.rs
@@ -1,4 +1,4 @@
-// Copyright 2018-2019 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -15,7 +15,8 @@
// along with this program. If not, see .
use super::Nonce;
-use ccrypto::aes::{self, SymmetricCipherError};
+use ccrypto::aes;
+use ccrypto::error::SymmError;
use ccrypto::Blake;
use ckey::Secret;
use primitives::H256;
@@ -26,8 +27,6 @@ pub struct Session {
nonce: Nonce,
}
-type Error = SymmetricCipherError;
-
impl Session {
pub fn new_with_zero_nonce(secret: Secret) -> Self {
Self::new(secret, 0)
@@ -52,11 +51,11 @@ impl Session {
self.nonce
}
- pub fn encrypt(&self, data: &[u8]) -> Result, Error> {
+ pub fn encrypt(&self, data: &[u8]) -> Result, SymmError> {
Ok(aes::encrypt(&data, &self.secret, &self.nonce())?)
}
- pub fn decrypt(&self, data: &[u8]) -> Result, Error> {
+ pub fn decrypt(&self, data: &[u8]) -> Result, SymmError> {
Ok(aes::decrypt(&data, &self.secret, &self.nonce())?)
}
diff --git a/network/src/stream.rs b/network/src/stream.rs
index 6651def14a..ffe1f30edb 100644
--- a/network/src/stream.rs
+++ b/network/src/stream.rs
@@ -109,6 +109,9 @@ impl TryStream {
assert!(read_size < len_of_len, "{} should be less than {}", read_size, len_of_len);
if let Some(new_read_size) = self.stream.try_read(&mut bytes[(1 + read_size)..=len_of_len])? {
+ if new_read_size == 0 {
+ return Err(io::Error::new(io::ErrorKind::ConnectionAborted, "EOF"))
+ }
read_size += new_read_size;
};
if len_of_len == read_size {
@@ -128,7 +131,7 @@ impl TryStream {
if let Some(read_size) = self.stream.try_read(&mut bytes)? {
if read_size == 0 {
- return Ok(None)
+ return Err(io::Error::new(io::ErrorKind::ConnectionAborted, "EOF").into())
}
debug_assert_eq!(1, read_size);
if 0xf8 <= bytes[0] {
@@ -184,6 +187,9 @@ impl TryStream {
while remain_length != 0 {
let to_be_read = ::std::cmp::min(remain_length, 1024);
if let Some(read_size) = self.stream.try_read(&mut bytes[0..to_be_read])? {
+ if read_size == 0 {
+ return Err(io::Error::new(io::ErrorKind::ConnectionAborted, "EOF").into())
+ }
result.extend_from_slice(&bytes[..read_size]);
debug_assert!(remain_length >= read_size);
remain_length -= read_size;
diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml
index aea4fc5467..5b97f9465d 100644
--- a/rpc/Cargo.toml
+++ b/rpc/Cargo.toml
@@ -9,7 +9,7 @@ edition = "2018"
[dependencies]
cidr = "0.0.4"
codechain-core = { path = "../core" }
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
codechain-json = { path = "../json" }
codechain-key = { path = "../key" }
codechain-keystore = { path = "../keystore" }
@@ -23,7 +23,7 @@ kvdb = "0.1"
kvdb-rocksdb = "0.1"
lazy_static = "1.2"
log = "0.4.6"
-parking_lot = "0.6.0"
+parking_lot = "0.11.0"
primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" }
rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.4" }
serde = "1.0"
diff --git a/rpc/src/v1/impls/devel.rs b/rpc/src/v1/impls/devel.rs
index fb39ecf846..8231b5cd63 100644
--- a/rpc/src/v1/impls/devel.rs
+++ b/rpc/src/v1/impls/devel.rs
@@ -1,4 +1,4 @@
-// Copyright 2018-2019 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -29,7 +29,7 @@ use csync::BlockSyncEvent;
use ctypes::transaction::{
Action, AssetMintOutput, AssetOutPoint, AssetTransferInput, AssetTransferOutput, Transaction,
};
-use ctypes::{Tracker, TxHash};
+use ctypes::{BlockHash, Tracker, TxHash};
use jsonrpc_core::Result;
use kvdb::KeyValueDB;
use primitives::{H160, H256};
@@ -106,6 +106,26 @@ where
}
}
+ fn get_peer_best_block_hashes(&self) -> Result> {
+ if let Some(block_sync) = self.block_sync.as_ref() {
+ let (sender, receiver) = unbounded_event_callback();
+ block_sync.send(BlockSyncEvent::GetPeerBestBlockHashes(sender)).unwrap();
+ Ok(receiver.iter().collect())
+ } else {
+ Ok(Vec::new())
+ }
+ }
+
+ fn get_target_block_hashes(&self) -> Result> {
+ if let Some(block_sync) = self.block_sync.as_ref() {
+ let (sender, receiver) = unbounded_event_callback();
+ block_sync.send(BlockSyncEvent::GetTargetBlockHashes(sender)).unwrap();
+ Ok(receiver.iter().collect())
+ } else {
+ Ok(Vec::new())
+ }
+ }
+
fn test_tps(&self, setting: TPSTestSetting) -> Result {
let common_params = self.client.common_params(BlockId::Latest).unwrap();
let mint_fee = common_params.min_asset_mint_cost();
diff --git a/rpc/src/v1/impls/mempool.rs b/rpc/src/v1/impls/mempool.rs
index c5cb2c2db9..9a386a5eac 100644
--- a/rpc/src/v1/impls/mempool.rs
+++ b/rpc/src/v1/impls/mempool.rs
@@ -16,7 +16,7 @@
use super::super::errors;
use super::super::traits::Mempool;
-use super::super::types::PendingTransactions;
+use super::super::types::{MemPoolMinFees, PendingTransactions};
use ccore::{BlockChainClient, EngineInfo, MiningBlockChainClient, SignedTransaction};
use cjson::bytes::Bytes;
use ckey::{Address, PlatformAddress};
@@ -132,4 +132,8 @@ where
self.client.register_immune_users(immune_user_vec);
Ok(())
}
+
+ fn get_machine_minimum_fees(&self) -> Result {
+ Ok(MemPoolMinFees::from(self.client.mem_pool_min_fees()))
+ }
}
diff --git a/rpc/src/v1/traits/devel.rs b/rpc/src/v1/traits/devel.rs
index 351c1ab096..8ea0f735f0 100644
--- a/rpc/src/v1/traits/devel.rs
+++ b/rpc/src/v1/traits/devel.rs
@@ -1,4 +1,4 @@
-// Copyright 2018 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -16,6 +16,7 @@
use super::super::types::TPSTestSetting;
use cjson::bytes::Bytes;
+use ctypes::BlockHash;
use jsonrpc_core::Result;
use primitives::H256;
use std::net::SocketAddr;
@@ -37,6 +38,12 @@ pub trait Devel {
#[rpc(name = "devel_getBlockSyncPeers")]
fn get_block_sync_peers(&self) -> Result>;
+ #[rpc(name = "devel_getPeerBestBlockHashes")]
+ fn get_peer_best_block_hashes(&self) -> Result>;
+
+ #[rpc(name = "devel_getTargetBlockHashes")]
+ fn get_target_block_hashes(&self) -> Result>;
+
#[rpc(name = "devel_testTPS")]
fn test_tps(&self, setting: TPSTestSetting) -> Result;
}
diff --git a/rpc/src/v1/traits/mempool.rs b/rpc/src/v1/traits/mempool.rs
index 8ea69d4e25..392cd06a3a 100644
--- a/rpc/src/v1/traits/mempool.rs
+++ b/rpc/src/v1/traits/mempool.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-use super::super::types::PendingTransactions;
+use super::super::types::{MemPoolMinFees, PendingTransactions};
use cjson::bytes::Bytes;
use ckey::PlatformAddress;
use ctypes::{Tracker, TxHash};
@@ -70,4 +70,7 @@ pub trait Mempool {
#[rpc(name = "mempool_registerImmuneAccounts")]
fn register_immune_accounts(&self, immune_user_list: Vec) -> Result<()>;
+
+ #[rpc(name = "mempool_getMachineMinimumFees")]
+ fn get_machine_minimum_fees(&self) -> Result;
}
diff --git a/rpc/src/v1/types/mem_pool.rs b/rpc/src/v1/types/mem_pool.rs
new file mode 100644
index 0000000000..6ba73aa20d
--- /dev/null
+++ b/rpc/src/v1/types/mem_pool.rs
@@ -0,0 +1,55 @@
+// Copyright 2020 Kodebox, Inc.
+// This file is part of CodeChain.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MemPoolMinFees {
+ min_pay_transaction_cost: u64,
+ min_set_regular_key_transaction_cost: u64,
+ min_create_shard_transaction_cost: u64,
+ min_set_shard_owners_transaction_cost: u64,
+ min_set_shard_users_transaction_cost: u64,
+ min_wrap_ccc_transaction_cost: u64,
+ min_custom_transaction_cost: u64,
+ min_store_transaction_cost: u64,
+ min_remove_transaction_cost: u64,
+ min_asset_mint_cost: u64,
+ min_asset_transfer_cost: u64,
+ min_asset_scheme_change_cost: u64,
+ min_asset_supply_increase_cost: u64,
+ min_asset_unwrap_ccc_cost: u64,
+}
+
+impl From for MemPoolMinFees {
+ fn from(fees: ccore::MemPoolMinFees) -> Self {
+ Self {
+ min_pay_transaction_cost: fees.min_pay_transaction_cost,
+ min_set_regular_key_transaction_cost: fees.min_set_regular_key_transaction_cost,
+ min_create_shard_transaction_cost: fees.min_create_shard_transaction_cost,
+ min_set_shard_owners_transaction_cost: fees.min_set_shard_owners_transaction_cost,
+ min_set_shard_users_transaction_cost: fees.min_set_shard_users_transaction_cost,
+ min_wrap_ccc_transaction_cost: fees.min_wrap_ccc_transaction_cost,
+ min_custom_transaction_cost: fees.min_custom_transaction_cost,
+ min_store_transaction_cost: fees.min_store_transaction_cost,
+ min_remove_transaction_cost: fees.min_remove_transaction_cost,
+ min_asset_mint_cost: fees.min_asset_mint_cost,
+ min_asset_transfer_cost: fees.min_asset_transfer_cost,
+ min_asset_scheme_change_cost: fees.min_asset_scheme_change_cost,
+ min_asset_supply_increase_cost: fees.min_asset_supply_increase_cost,
+ min_asset_unwrap_ccc_cost: fees.min_asset_unwrap_ccc_cost,
+ }
+ }
+}
diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs
index 66d9b30ba5..8f73c25e24 100644
--- a/rpc/src/v1/types/mod.rs
+++ b/rpc/src/v1/types/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2018-2019 Kodebox, Inc.
+// Copyright 2018-2020 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@ mod asset_input;
mod asset_output;
mod asset_scheme;
mod block;
+mod mem_pool;
mod text;
mod transaction;
mod unsigned_transaction;
@@ -34,6 +35,7 @@ pub use self::asset::OwnedAsset;
pub use self::asset_scheme::AssetScheme;
pub use self::block::Block;
pub use self::block::BlockNumberAndHash;
+pub use self::mem_pool::MemPoolMinFees;
pub use self::text::Text;
pub use self::transaction::{PendingTransactions, Transaction};
pub use self::unsigned_transaction::UnsignedTransaction;
diff --git a/spec/JSON-RPC.md b/spec/JSON-RPC.md
index 486a0cdb0b..8e9f3f5d73 100644
--- a/spec/JSON-RPC.md
+++ b/spec/JSON-RPC.md
@@ -328,6 +328,7 @@ When `Transaction` is included in any response, there will be an additional fiel
* [mempool_banAccounts](#mempool_banaccounts)
* [mempool_registerImmuneAccounts](#mempool_registerimmuneaccounts)
* [mempool_getRegisteredImmuneAccounts](#mempool_getregisteredimmuneaccounts)
+ * [mempool_getMachineMinimumFees](#mempool_getmachineminimumfees)
***
* [engine_getCoinbase](#engine_getcoinbase)
* [engine_getBlockReward](#engine_getblockreward)
@@ -370,7 +371,8 @@ When `Transaction` is included in any response, there will be an additional fiel
* [devel_startSealing](#devel_startsealing)
* [devel_stopSealing](#devel_stopsealing)
* [devel_getBlockSyncPeers](#devel_getblocksyncpeers)
-
+ * [devel_getPeerBestBlockHashes](#devel_getpeerbestblockhases)
+ * [devel_getTargetBlockHashes](#devel_gettargetblockhashes)
# Specification
@@ -1987,6 +1989,65 @@ curl \
[Back to **List of methods**](#list-of-methods)
+## mempool_getMachineMinimumFees
+Get minimum fees configured by the machine.
+
+### Params
+No parameters
+
+### Returns
+{
+ "minAssetMintCost": `number`,
+ "minAssetSchemeChangeCost":`number`,
+ "minAssetSupplyIncreaseCost": `number`,
+ "minAssetTransferCost":`number`,
+ "minAssetUnwrapCccCost":`number`,
+ "minCreateShardTransactionCost":`number`,
+ "minCustomTransactionCost":`number`,
+ "minStoreTransactionCost": `number`,
+ "minRemoveTransactionCost": `number`,
+ "minPayTransactionCost":`number`,
+ "minSetRegularKeyTransactionCost":`number`,
+ "minSetShardOwnersTransactionCost":`number`,
+ "minSetShardUsersTransactionCost":`number`,
+ "minWrapCccTransactionCost":`number`
+}
+
+### Request Example
+```
+curl \
+ -H 'Content-Type: application/json' \
+ -d '{"jsonrpc": "2.0", "method": "mempool_getMachineMinimumFees", "params": [], "id": null}' \
+ localhost:8080
+```
+
+### Response Example
+```
+{
+ "jsonrpc":"2.0",
+ "result":{
+ "minAssetMintCost":0,
+ "minAssetSchemeChangeCost":0,
+ "minAssetSupplyIncreaseCost":0,
+ "minAssetTransferCost":0,
+ "minAssetUnwrapCccCost":0,
+ "minCreateShardTransactionCost":0,
+ "minCustomTransactionCost":0,
+ "minStoreTransactionCost": 0,
+ "minRemoveTransactionCost": 0,
+ "minPayTransactionCost":0,
+ "minSetRegularKeyTransactionCost":0,
+ "minSetShardOwnersTransactionCost":0,
+ "minSetShardUsersTransactionCost":0,
+ "minWrapCccTransactionCost":0
+ },
+ "id":null
+}
+
+```
+
+[Back to **List of methods**](#list-of-methods)
+
## engine_getCoinbase
Gets coinbase's account id.
@@ -3093,6 +3154,76 @@ No parameters
[Back to **List of methods**](#list-of-methods)
+## devel_getPeerBestBlockHashes
+
+Get IP address and best block hash of each peer.
+
+### Params
+
+No parameters
+
+### Returns
+
+[ 'string', 'H256' ][]
+
+### Request Example
+
+```
+ curl \
+ -H 'Content-Type: application/json' \
+ -d '{"jsonrpc": "2.0", "method": "devel_getPeerBestBlockHashes", "params": [], "id": 3}' \
+ localhost:8080
+```
+
+### Response Example
+```
+{
+ "jsonrpc":"2.0",
+ "result": [
+ ["1.2.3.4:3485", "0x56642f04d519ae3262c7ba6facf1c5b11450ebaeb7955337cfbc45420d573077"],
+ ["1.2.3.5:3485", "0x7f7104b580f9418d444560009e5a92a4573d42d2c51cd0c6045afdc761826249"]
+ ],
+ "id":3
+}
+```
+
+[Back to **List of methods**](#list-of-methods)
+
+## devel_getTargetBlockHashes
+
+Get hashes of target blocks
+
+### Params
+
+No parameters
+
+### Returns
+
+'`H256[]`
+
+### Request Example
+
+```
+ curl \
+ -H 'Content-Type: application/json' \
+ -d '{"jsonrpc": "2.0", "method": "devel_getTargetBlockHashes", "params": [], "id": 3}' \
+ localhost:8080
+```
+
+### Response Example
+```
+{
+ "jsonrpc":"2.0",
+ "result": [
+ "0x56642f04d519ae3262c7ba6facf1c5b11450ebaeb7955337cfbc45420d573077",
+ "0x7f7104b580f9418d444560009e5a92a4573d42d2c51cd0c6045afdc761826249"
+ ],
+ "id":3
+}
+```
+
+[Back to **List of methods**](#list-of-methods)
+
## devel_testTPS
Test TPS as the parameters.
diff --git a/state/Cargo.toml b/state/Cargo.toml
index 6124dd69d5..b1e6d7c23b 100644
--- a/state/Cargo.toml
+++ b/state/Cargo.toml
@@ -5,8 +5,8 @@ authors = ["CodeChain Team "]
edition = "2018"
[dependencies]
-codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" }
-codechain-db = { git = "https://github.com/CodeChain-io/rust-codechain-db.git", version = "0.1" }
+codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.2" }
+codechain-db = { git = "https://github.com/CodeChain-io/rust-codechain-db.git", version = "0.2" }
codechain-logger = { path = "../util/logger" }
codechain-key = { path = "../key" }
codechain-types = { path = "../types" }
@@ -15,8 +15,8 @@ kvdb = "0.1"
kvdb-memorydb = "0.1"
log = "0.4.6"
lru-cache = "0.1.1"
-merkle-trie = { git = "https://github.com/CodeChain-io/rust-merkle-trie.git", version = "0.1" }
-parking_lot = "0.6.0"
+merkle-trie = { git = "https://github.com/CodeChain-io/rust-merkle-trie.git", version = "0.4" }
+parking_lot = "0.11.0"
primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" }
rlp = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.4" }
rlp_derive = { git = "https://github.com/CodeChain-io/rlp.git", version = "0.2" }
diff --git a/state/src/cache/top_cache.rs b/state/src/cache/top_cache.rs
index d8efc422ad..e1b81d2b2f 100644
--- a/state/src/cache/top_cache.rs
+++ b/state/src/cache/top_cache.rs
@@ -128,10 +128,6 @@ impl TopCache {
self.shard.get_mut(a, db)
}
- #[allow(dead_code)]
- pub fn remove_shard(&self, address: &ShardAddress) {
- self.shard.remove(address)
- }
pub fn text(&self, a: &H256, db: &dyn Trie) -> TrieResult