From ea0c13c0a4d1ee8db2a984c95867e565f2a92a5c Mon Sep 17 00:00:00 2001 From: Artem Vorotnikov Date: Wed, 2 Sep 2020 18:43:14 +0300 Subject: [PATCH] Remove private transactions --- Cargo.lock | 55 - Cargo.toml | 1 - README.md | 4 - ethcore/private-tx/Cargo.toml | 44 - ethcore/private-tx/res/keys_acl.json | 43 - ethcore/private-tx/res/private.evm | 1 - ethcore/private-tx/res/private.json | 171 --- ethcore/private-tx/src/encryptor.rs | 288 ----- ethcore/private-tx/src/error.rs | 202 ---- ethcore/private-tx/src/key_server_keys.rs | 195 ---- ethcore/private-tx/src/lib.rs | 1004 ----------------- ethcore/private-tx/src/messages.rs | 119 -- .../private-tx/src/private_transactions.rs | 278 ----- ethcore/private-tx/tests/private_contract.rs | 421 ------- ethcore/service/Cargo.toml | 1 - ethcore/service/src/error.rs | 2 - ethcore/service/src/lib.rs | 3 +- ethcore/service/src/service.rs | 72 -- ethcore/src/client/chain_notify.rs | 4 - ethcore/src/client/mod.rs | 1 - ethcore/src/client/private_notify.rs | 23 - ethcore/src/test_helpers.rs | 2 - ethcore/sync/Cargo.toml | 1 - ethcore/sync/src/api.rs | 35 +- ethcore/sync/src/chain/handler.rs | 92 +- ethcore/sync/src/chain/mod.rs | 69 +- ethcore/sync/src/chain/propagator.rs | 33 +- ethcore/sync/src/chain/sync_packet.rs | 6 +- ethcore/sync/src/lib.rs | 4 - ethcore/sync/src/private_tx.rs | 63 -- ethcore/sync/src/tests/helpers.rs | 44 +- ethcore/sync/src/tests/mod.rs | 1 - ethcore/sync/src/tests/private.rs | 200 ---- parity/account_utils.rs | 66 +- parity/blockchain.rs | 9 - parity/cli/mod.rs | 58 +- parity/cli/tests/config.full.toml | 9 - parity/configuration.rs | 36 - parity/lib.rs | 1 - parity/modules.rs | 4 +- parity/rpc_apis.rs | 33 +- parity/run.rs | 38 +- parity/snapshot.rs | 5 - rpc/Cargo.toml | 1 - rpc/src/lib.rs | 1 - rpc/src/v1/helpers/errors.rs | 26 - rpc/src/v1/impls/mod.rs | 2 - rpc/src/v1/impls/private.rs | 142 --- rpc/src/v1/mod.rs | 2 +- rpc/src/v1/traits/mod.rs | 2 - rpc/src/v1/traits/private.rs | 55 - rpc/src/v1/types/mod.rs | 2 - rpc/src/v1/types/private_receipt.rs | 51 - util/fetch/src/client.rs | 5 - 54 files changed, 38 insertions(+), 3992 deletions(-) delete mode 100644 ethcore/private-tx/Cargo.toml delete mode 100644 ethcore/private-tx/res/keys_acl.json delete mode 100644 ethcore/private-tx/res/private.evm delete mode 100644 ethcore/private-tx/res/private.json delete mode 100644 ethcore/private-tx/src/encryptor.rs delete mode 100644 ethcore/private-tx/src/error.rs delete mode 100644 ethcore/private-tx/src/key_server_keys.rs delete mode 100644 ethcore/private-tx/src/lib.rs delete mode 100644 ethcore/private-tx/src/messages.rs delete mode 100644 ethcore/private-tx/src/private_transactions.rs delete mode 100644 ethcore/private-tx/tests/private_contract.rs delete mode 100644 ethcore/src/client/private_notify.rs delete mode 100644 ethcore/sync/src/private_tx.rs delete mode 100644 ethcore/sync/src/tests/private.rs delete mode 100644 rpc/src/v1/impls/private.rs delete mode 100644 rpc/src/v1/traits/private.rs delete mode 100644 rpc/src/v1/types/private_receipt.rs diff --git a/Cargo.lock b/Cargo.lock index 9f52df9b6..af58a1e9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -574,17 +574,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "derive_more" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "difference" version = "1.0.0" @@ -1063,45 +1052,6 @@ dependencies = [ "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ethcore-private-tx" -version = "1.0.0" -dependencies = [ - "common-types 0.1.0", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-contract 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethabi-derive 6.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore 1.12.0", - "ethcore-call-contract 0.1.0", - "ethcore-io 1.12.0", - "ethcore-miner 1.12.0", - "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ethjson 0.1.0", - "ethkey 0.3.0", - "fetch 0.1.0", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (git+https://github.com/cheme/heapsize.git?branch=ec-macfix)", - "keccak-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-crypto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "patricia-trie-ethereum 0.1.0", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rlp_derive 0.1.0", - "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-pool 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ethcore-secretstore" version = "1.0.0" @@ -1153,7 +1103,6 @@ dependencies = [ "ethcore-blockchain 0.1.0", "ethcore-db 0.1.0", "ethcore-io 1.12.0", - "ethcore-private-tx 1.0.0", "ethcore-sync 1.12.0", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1189,7 +1138,6 @@ dependencies = [ "ethcore-io 1.12.0", "ethcore-network 1.12.0", "ethcore-network-devp2p 1.12.0", - "ethcore-private-tx 1.0.0", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.3.0", "ethstore 0.2.1", @@ -2567,7 +2515,6 @@ dependencies = [ "ethcore-logger 1.12.0", "ethcore-miner 1.12.0", "ethcore-network 1.12.0", - "ethcore-private-tx 1.0.0", "ethcore-secretstore 1.0.0", "ethcore-service 0.1.0", "ethcore-sync 1.12.0", @@ -2676,7 +2623,6 @@ dependencies = [ "ethcore-logger 1.12.0", "ethcore-miner 1.12.0", "ethcore-network 1.12.0", - "ethcore-private-tx 1.0.0", "ethcore-sync 1.12.0", "ethereum-types 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethjson 0.1.0", @@ -4695,7 +4641,6 @@ dependencies = [ "checksum ct-logs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b4660f8b07a560a88c02d76286edb9f0d5d64e495d2b0f233186155aa51be1f" "checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" "checksum ctrlc 1.1.1 (git+https://github.com/paritytech/rust-ctrlc.git)" = "" -"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" diff --git a/Cargo.toml b/Cargo.toml index 0c02293cf..c0c138bfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,6 @@ ethcore-io = { path = "util/io" } ethcore-logger = { path = "parity/logger" } ethcore-miner = { path = "miner" } ethcore-network = { path = "util/network" } -ethcore-private-tx = { path = "ethcore/private-tx" } ethcore-service = { path = "ethcore/service" } ethcore-sync = { path = "ethcore/sync" } ethereum-types = "0.4" diff --git a/README.md b/README.md index ca8cd59a6..330220ad6 100644 --- a/README.md +++ b/README.md @@ -244,10 +244,6 @@ Caching, Importing Blocks, and Block Information ```bash node-filter ``` - * Parity Private Transactions - ```bash - ethcore-private-tx - ``` * Parity Ethereum (EthCore) Client & Network Service Creation & Registration with the I/O Subsystem ```bash ethcore-service diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml deleted file mode 100644 index 0ae156dfb..000000000 --- a/ethcore/private-tx/Cargo.toml +++ /dev/null @@ -1,44 +0,0 @@ -[package] -description = "Parity Private Transactions" -name = "ethcore-private-tx" -version = "1.0.0" -license = "GPL-3.0" -authors = ["Parity Technologies "] - -[dependencies] -common-types = { path = "../types" } -derive_more = "0.14.0" -ethabi = "6.0" -ethabi-contract = "6.0" -ethabi-derive = "6.0" -ethcore = { path = ".." } -ethcore-call-contract = { path = "../call-contract" } -ethcore-io = { path = "../../util/io" } -ethcore-miner = { path = "../../miner" } -ethereum-types = "0.4" -ethjson = { path = "../../json" } -ethkey = { path = "../../accounts/ethkey" } -fetch = { path = "../../util/fetch" } -futures = "0.1" -heapsize = "0.4" -keccak-hash = "0.1.2" -log = "0.4" -parity-bytes = "0.1" -parity-crypto = "0.3.0" -parking_lot = "0.7" -trie-db = "0.11.0" -patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" } -rand = "0.3" -rlp = { version = "0.3.0", features = ["ethereum"] } -rlp_derive = { path = "../../util/rlp-derive" } -rustc-hex = "1.0" -serde = "1.0" -serde_derive = "1.0" -serde_json = "1.0" -tiny-keccak = "1.4" -transaction-pool = "2.0.1" -url = "2" - -[dev-dependencies] -env_logger = "0.5" -ethcore = { path = "..", features = ["test-helpers"] } diff --git a/ethcore/private-tx/res/keys_acl.json b/ethcore/private-tx/res/keys_acl.json deleted file mode 100644 index 3ec2daf9e..000000000 --- a/ethcore/private-tx/res/keys_acl.json +++ /dev/null @@ -1,43 +0,0 @@ -[ - { - "constant": true, - "inputs": [ - { - "name":"user", - "type":"address" - } - ], - "name": "availableKeys", - "outputs": [ - { - "name": "", - "type": "bytes32[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant":true, - "inputs": [ - { - "name":"user", - "type":"address" - }, - { - "name":"document", - "type":"bytes32" - } - ], - "name":"checkPermissions", - "outputs": [ - { - "name":"", - "type":"bool" - } - ], - "payable":false, - "type":"function" - } -] diff --git a/ethcore/private-tx/res/private.evm b/ethcore/private-tx/res/private.evm deleted file mode 100644 index e1da9bb60..000000000 --- a/ethcore/private-tx/res/private.evm +++ /dev/null @@ -1 +0,0 @@ -60806040523480156200001157600080fd5b5060405162000d5238038062000d52833981018060405281019080805182019291906020018051820192919060200180518201929190505050826000908051906020019062000062929190620000a6565b5081600290805190602001906200007b92919062000135565b5080600190805190602001906200009492919062000135565b5060016003819055505050506200022a565b82805482825590600052602060002090810192821562000122579160200282015b82811115620001215782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190620000c7565b5b509050620001319190620001bc565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200017857805160ff1916838001178555620001a9565b82800160010185558215620001a9579182015b82811115620001a85782518255916020019190600101906200018b565b5b509050620001b8919062000202565b5090565b620001ff91905b80821115620001fb57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101620001c3565b5090565b90565b6200022791905b808211156200022357600081600090555060010162000209565b5090565b90565b610b18806200023a6000396000f30060806040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630d8e6e2c1461009357806317ac53a2146100c457806324c12bf6146101f657806335aa2e44146102865780639326c281146102f3578063affed0e01461037c578063b7ab4db5146103a7578063c19d93fb14610413575b600080fd5b34801561009f57600080fd5b506100a86104a3565b604051808260ff1660ff16815260200191505060405180910390f35b3480156100d057600080fd5b506101f4600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091929192905050506104ac565b005b34801561020257600080fd5b5061020b610765565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561024b578082015181840152602081019050610230565b50505050905090810190601f1680156102785780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029257600080fd5b506102b160048036038101908080359060200190929190505050610803565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102ff57600080fd5b5061037a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610841565b005b34801561038857600080fd5b50610391610915565b6040518082815260200191505060405180910390f35b3480156103b357600080fd5b506103bc61091b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156103ff5780820151818401526020810190506103e4565b505050509050019250505060405180910390f35b34801561041f57600080fd5b506104286109a9565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561046857808201518184015260208101905061044d565b50505050905090810190601f1680156104955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60006002905090565b6000806040805190810160405280876040518082805190602001908083835b6020831015156104f057805182526020820191506020810190506020830392506104cb565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200160035460010260001916600019168152506040516020018082600260200280838360005b8381101561056957808201518184015260208101905061054e565b505050509050019150506040516020818303038152906040526040518082805190602001908083835b6020831015156105b75780518252602082019150602081019050602083039250610592565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209150600090505b60008054905081101561073a5760008181548110151561060757fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600183878481518110151561065957fe5b90602001906020020151878581518110151561067157fe5b90602001906020020151878681518110151561068957fe5b90602001906020020151604051600081526020016040526040518085600019166000191681526020018460ff1660ff1681526020018360001916600019168152602001826000191660001916815260200194505050505060206040516020810390808403906000865af1158015610704573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614151561072d57fe5b80806001019150506105eb565b8560019080519060200190610750929190610a47565b50600160035401600381905550505050505050565b60028054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107fb5780601f106107d0576101008083540402835291602001916107fb565b820191906000526020600020905b8154815290600101906020018083116107de57829003601f168201915b505050505081565b60008181548110151561081257fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7fd75b949e4bbba98bcf6d2878e9175f5608dde180a67ba25d0f2020067e17fdac8282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108d65780820151818401526020810190506108bb565b50505050905090810190601f1680156109035780820380516001836020036101000a031916815260200191505b50935050505060405180910390a15050565b60035481565b6060600080548060200260200160405190810160405280929190818152602001828054801561099f57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610955575b5050505050905090565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a3f5780601f10610a1457610100808354040283529160200191610a3f565b820191906000526020600020905b815481529060010190602001808311610a2257829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610a8857805160ff1916838001178555610ab6565b82800160010185558215610ab6579182015b82811115610ab5578251825591602001919060010190610a9a565b5b509050610ac39190610ac7565b5090565b610ae991905b80821115610ae5576000816000905550600101610acd565b5090565b905600a165627a7a723058205bbab96bfbda16ccdb4900d9280aa9d511c3d3687be1ca598dd784987f55ebb70029 diff --git a/ethcore/private-tx/res/private.json b/ethcore/private-tx/res/private.json deleted file mode 100644 index 0d8f17543..000000000 --- a/ethcore/private-tx/res/private.json +++ /dev/null @@ -1,171 +0,0 @@ -[ - { - "constant": true, - "inputs": [], - "name": "getVersion", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newState", - "type": "bytes" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "setState", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "code", - "outputs": [ - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "validators", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "changesOriginator", - "type": "address" - }, - { - "name": "originalTransactionHash", - "type": "bytes" - } - ], - "name": "notifyChanges", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "nonce", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getValidators", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "state", - "outputs": [ - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "name": "initialValidators", - "type": "address[]" - }, - { - "name": "initialCode", - "type": "bytes" - }, - { - "name": "initialState", - "type": "bytes" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "changesOriginator", - "type": "address" - }, - { - "indexed": false, - "name": "originalTransactionHash", - "type": "bytes" - } - ], - "name": "PrivateStateChanged", - "type": "event" - } -] \ No newline at end of file diff --git a/ethcore/private-tx/src/encryptor.rs b/ethcore/private-tx/src/encryptor.rs deleted file mode 100644 index 107e5f897..000000000 --- a/ethcore/private-tx/src/encryptor.rs +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -//! Encryption providers. - -use super::{key_server_keys::address_to_key, Signer}; -use bytes::{Bytes, ToPretty}; -use crypto; -use error::Error; -use ethereum_types::{Address, H128, H256}; -use ethjson; -use ethkey::{Public, Signature}; -use fetch::{BodyReader, Client as FetchClient, Fetch, Method, Request}; -use futures::Future; -use parking_lot::Mutex; -use std::{ - collections::{hash_map::Entry, HashMap}, - io::Read, - iter::repeat, - str::FromStr, - sync::Arc, - time::{Duration, Instant}, -}; -use url::Url; - -/// Initialization vector length. -const INIT_VEC_LEN: usize = 16; - -/// Duration of storing retrieved keys (in ms) -const ENCRYPTION_SESSION_DURATION: u64 = 30 * 1000; - -/// Trait for encryption/decryption operations. -pub trait Encryptor: Send + Sync + 'static { - /// Generate unique contract key && encrypt passed data. Encryption can only be performed once. - fn encrypt( - &self, - contract_address: &Address, - initialisation_vector: &H128, - plain_data: &[u8], - ) -> Result; - - /// Decrypt data using previously generated contract key. - fn decrypt(&self, contract_address: &Address, cypher: &[u8]) -> Result; -} - -/// Configuration for key server encryptor -#[derive(Default, PartialEq, Debug, Clone)] -pub struct EncryptorConfig { - /// URL to key server - pub base_url: Option, - /// Key server's threshold - pub threshold: u32, - /// Account used for signing requests to key server - pub key_server_account: Option
, -} - -struct EncryptionSession { - key: Bytes, - end_time: Instant, -} - -/// SecretStore-based encryption/decryption operations. -pub struct SecretStoreEncryptor { - config: EncryptorConfig, - client: FetchClient, - sessions: Mutex>, - signer: Arc, -} - -impl SecretStoreEncryptor { - /// Create new encryptor - pub fn new( - config: EncryptorConfig, - client: FetchClient, - signer: Arc, - ) -> Result { - Ok(SecretStoreEncryptor { - config, - client, - signer, - sessions: Mutex::default(), - }) - } - - /// Ask secret store for key && decrypt the key. - fn retrieve_key( - &self, - url_suffix: &str, - use_post: bool, - contract_address: &Address, - ) -> Result { - // check if the key was already cached - if let Some(key) = self.obtained_key(contract_address) { - return Ok(key); - } - let contract_address_signature = self.sign_contract_address(contract_address)?; - let requester = self - .config - .key_server_account - .ok_or_else(|| Error::KeyServerAccountNotSet)?; - - // key id in SS is H256 && we have H160 here => expand with assitional zeros - let contract_address_extended: H256 = contract_address.into(); - let base_url = self - .config - .base_url - .clone() - .ok_or_else(|| Error::KeyServerNotSet)?; - - // prepare request url - let url = format!( - "{}/{}/{}{}", - base_url, - contract_address_extended.to_hex(), - contract_address_signature, - url_suffix, - ); - - // send HTTP request - let method = if use_post { Method::POST } else { Method::GET }; - - let url = Url::from_str(&url).map_err(|e| Error::Encrypt(e.to_string()))?; - let response = self - .client - .fetch(Request::new(url, method), Default::default()) - .wait() - .map_err(|e| Error::Encrypt(e.to_string()))?; - - if response.is_not_found() { - return Err(Error::EncryptionKeyNotFound(*contract_address)); - } - - if !response.is_success() { - return Err(Error::Encrypt( - response - .status() - .canonical_reason() - .unwrap_or("unknown") - .into(), - )); - } - - // read HTTP response - let mut result = String::new(); - BodyReader::new(response).read_to_string(&mut result)?; - - // response is JSON string (which is, in turn, hex-encoded, encrypted Public) - let encrypted_bytes: ethjson::bytes::Bytes = result - .trim_matches('\"') - .parse() - .map_err(|e| Error::Encrypt(e))?; - - // decrypt Public - let decrypted_bytes = - self.signer - .decrypt(requester, &crypto::DEFAULT_MAC, &encrypted_bytes)?; - let decrypted_key = Public::from_slice(&decrypted_bytes); - - // and now take x coordinate of Public as a key - let key: Bytes = (*decrypted_key)[..INIT_VEC_LEN].into(); - - // cache the key in the session and clear expired sessions - self.sessions.lock().insert( - *contract_address, - EncryptionSession { - key: key.clone(), - end_time: Instant::now() + Duration::from_millis(ENCRYPTION_SESSION_DURATION), - }, - ); - self.clean_expired_sessions(); - Ok(key) - } - - fn clean_expired_sessions(&self) { - let mut sessions = self.sessions.lock(); - sessions.retain(|_, session| session.end_time < Instant::now()); - } - - fn obtained_key(&self, contract_address: &Address) -> Option { - let mut sessions = self.sessions.lock(); - let stored_session = sessions.entry(*contract_address); - match stored_session { - Entry::Occupied(session) => { - if Instant::now() > session.get().end_time { - session.remove_entry(); - None - } else { - Some(session.get().key.clone()) - } - } - Entry::Vacant(_) => None, - } - } - - fn sign_contract_address(&self, contract_address: &Address) -> Result { - let key_server_account = self - .config - .key_server_account - .ok_or_else(|| Error::KeyServerAccountNotSet)?; - Ok(self - .signer - .sign(key_server_account, address_to_key(contract_address))?) - } -} - -impl Encryptor for SecretStoreEncryptor { - fn encrypt( - &self, - contract_address: &Address, - initialisation_vector: &H128, - plain_data: &[u8], - ) -> Result { - // retrieve the key, try to generate it if it doesn't exist yet - let key = match self.retrieve_key("", false, contract_address) { - Ok(key) => Ok(key), - Err(Error::EncryptionKeyNotFound(_)) => { - trace!(target: "privatetx", "Key for account wasnt found in sstore. Creating. Address: {:?}", contract_address); - self.retrieve_key( - &format!("/{}", self.config.threshold), - true, - contract_address, - ) - } - Err(err) => Err(err), - }?; - - // encrypt data - let mut cypher = Vec::with_capacity(plain_data.len() + initialisation_vector.len()); - cypher.extend(repeat(0).take(plain_data.len())); - crypto::aes::encrypt_128_ctr(&key, initialisation_vector, plain_data, &mut cypher) - .map_err(|e| Error::Encrypt(e.to_string()))?; - cypher.extend_from_slice(&initialisation_vector); - - Ok(cypher) - } - - /// Decrypt data using previously generated contract key. - fn decrypt(&self, contract_address: &Address, cypher: &[u8]) -> Result { - // initialization vector takes INIT_VEC_LEN bytes - let cypher_len = cypher.len(); - if cypher_len < INIT_VEC_LEN { - return Err(Error::Decrypt("Invalid cypher".into())); - } - - // retrieve existing key - let key = self.retrieve_key("", false, contract_address)?; - - // use symmetric decryption to decrypt document - let (cypher, iv) = cypher.split_at(cypher_len - INIT_VEC_LEN); - let mut plain_data = Vec::with_capacity(cypher_len - INIT_VEC_LEN); - plain_data.extend(repeat(0).take(cypher_len - INIT_VEC_LEN)); - crypto::aes::decrypt_128_ctr(&key, &iv, cypher, &mut plain_data) - .map_err(|e| Error::Decrypt(e.to_string()))?; - Ok(plain_data) - } -} - -/// Dummy encryptor. -#[derive(Default)] -pub struct NoopEncryptor; - -impl Encryptor for NoopEncryptor { - fn encrypt( - &self, - _contract_address: &Address, - _initialisation_vector: &H128, - data: &[u8], - ) -> Result { - Ok(data.to_vec()) - } - - fn decrypt(&self, _contract_address: &Address, data: &[u8]) -> Result { - Ok(data.to_vec()) - } -} diff --git a/ethcore/private-tx/src/error.rs b/ethcore/private-tx/src/error.rs deleted file mode 100644 index 664003de7..000000000 --- a/ethcore/private-tx/src/error.rs +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -use derive_more::Display; -use ethcore::error::{Error as EthcoreError, ExecutionError}; -use ethereum_types::Address; -use ethkey::{crypto::Error as CryptoError, Error as KeyError}; -use ethtrie::TrieError; -use private_transactions::VerifiedPrivateTransaction; -use rlp::DecoderError; -use std::error; -use txpool::VerifiedTransaction; -use types::transaction::Error as TransactionError; - -type TxPoolError = txpool::Error<::Hash>; - -#[derive(Debug, Display)] -pub enum Error { - /// Error concerning the Rust standard library's IO subsystem. - #[display(fmt = "Io Error: {}", _0)] - Io(::std::io::Error), - /// RLP decoding error. - #[display(fmt = "Decoder Error: {}", _0)] - Decoder(DecoderError), - /// Error concerning TrieDBs. - #[display(fmt = "Trie Error: {}", _0)] - Trie(TrieError), - /// Transaction pool error. - #[display(fmt = "Transaction Pool Error: {}", _0)] - TxPool(TxPoolError), - /// Crypto error. - #[display(fmt = "Crypto Error {}", _0)] - Crypto(CryptoError), - /// Encryption error. - #[display(fmt = "Encryption error. ({})", _0)] - Encrypt(String), - /// Decryption error. - #[display(fmt = "Decryption error. ({})", _0)] - Decrypt(String), - /// Address not authorized. - #[display(fmt = "Private transaction execution is not authorised for {}", _0)] - NotAuthorised(Address), - /// Transaction creates more than one contract. - #[display(fmt = "Private transaction created too many contracts")] - TooManyContracts, - /// Contract call error. - #[display(fmt = "Contract call error. ({})", _0)] - Call(String), - /// State is not available. - #[display(fmt = "State is not available")] - StatePruned, - /// State is incorrect. - #[display(fmt = "State is incorrect")] - StateIncorrect, - /// Wrong private transaction type. - #[display(fmt = "Wrong private transaction type")] - BadTransactionType, - /// Contract does not exist or was not created. - #[display(fmt = "Contract does not exist or was not created")] - ContractDoesNotExist, - /// Reference to the client is corrupted. - #[display(fmt = "Reference to the client is corrupted")] - ClientIsMalformed, - /// Queue of private transactions for verification is full. - #[display(fmt = "Queue of private transactions for verification is full")] - QueueIsFull, - /// The transaction already exists in queue of private transactions. - #[display(fmt = "The transaction already exists in queue of private transactions.")] - PrivateTransactionAlreadyImported, - /// The information about private transaction is not found in the store. - #[display(fmt = "The information about private transaction is not found in the store.")] - PrivateTransactionNotFound, - /// Account for signing public transactions not set. - #[display(fmt = "Account for signing public transactions not set.")] - SignerAccountNotSet, - /// Account for validating private transactions not set. - #[display(fmt = "Account for validating private transactions not set.")] - ValidatorAccountNotSet, - /// Account for signing requests to key server not set. - #[display(fmt = "Account for signing requests to key server not set.")] - KeyServerAccountNotSet, - /// Encryption key is not found on key server. - #[display(fmt = "Encryption key is not found on key server for {}", _0)] - EncryptionKeyNotFound(Address), - /// Key server URL is not set. - #[display(fmt = "Key server URL is not set.")] - KeyServerNotSet, - /// VM execution error. - #[display(fmt = "VM execution error {}", _0)] - Execution(ExecutionError), - /// General signing error. - #[display(fmt = "General signing error {}", _0)] - Key(KeyError), - /// Error of transactions processing. - #[display(fmt = "Error of transactions processing {}", _0)] - Transaction(TransactionError), - /// General ethcore error. - #[display(fmt = "General ethcore error {}", _0)] - Ethcore(EthcoreError), - /// A convenient variant for String. - #[display(fmt = "{}", _0)] - Msg(String), -} - -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match self { - Error::Io(e) => Some(e), - Error::Decoder(e) => Some(e), - Error::Trie(e) => Some(e), - Error::TxPool(e) => Some(e), - Error::Crypto(e) => Some(e), - Error::Execution(e) => Some(e), - Error::Key(e) => Some(e), - Error::Transaction(e) => Some(e), - Error::Ethcore(e) => Some(e), - _ => None, - } - } -} - -impl From for Error { - fn from(s: String) -> Self { - Error::Msg(s) - } -} - -impl From for Error { - fn from(err: std::io::Error) -> Self { - Error::Io(err).into() - } -} - -impl From for Error { - fn from(err: KeyError) -> Self { - Error::Key(err).into() - } -} - -impl From for Error { - fn from(err: CryptoError) -> Self { - Error::Crypto(err).into() - } -} - -impl From for Error { - fn from(err: DecoderError) -> Self { - Error::Decoder(err).into() - } -} - -impl From for Error { - fn from(err: ExecutionError) -> Self { - Error::Execution(err).into() - } -} - -impl From for Error { - fn from(err: TransactionError) -> Self { - Error::Transaction(err).into() - } -} - -impl From for Error { - fn from(err: TrieError) -> Self { - Error::Trie(err).into() - } -} - -impl From for Error { - fn from(err: TxPoolError) -> Self { - Error::TxPool(err).into() - } -} - -impl From for Error { - fn from(err: EthcoreError) -> Self { - Error::Ethcore(err).into() - } -} - -impl From> for Error -where - Error: From, -{ - fn from(err: Box) -> Error { - Error::from(*err) - } -} diff --git a/ethcore/private-tx/src/key_server_keys.rs b/ethcore/private-tx/src/key_server_keys.rs deleted file mode 100644 index cab4d6adc..000000000 --- a/ethcore/private-tx/src/key_server_keys.rs +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! Wrapper around key server responsible for access keys processing. - -use call_contract::{CallContract, RegistryInfo}; -use ethabi::FunctionOutputDecoder; -use ethcore::client::BlockId; -use ethereum_types::{Address, H256}; -use parking_lot::RwLock; -use std::sync::Arc; - -const ACL_CHECKER_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_acl_checker"; - -use_contract!(keys_acl_contract, "res/keys_acl.json"); - -/// Returns the address (of the contract), that corresponds to the key -pub fn key_to_address(key: &H256) -> Address { - Address::from_slice(&key.to_vec()[..10]) -} - -/// Returns the key from the key server associated with the contract -pub fn address_to_key(contract_address: &Address) -> H256 { - // Current solution uses contract address extended with 0 as id - let contract_address_extended: H256 = contract_address.into(); - - H256::from_slice(&contract_address_extended) -} - -/// Trait for keys server keys provider. -pub trait KeyProvider: Send + Sync + 'static { - /// Account, that is used for communication with key server - fn key_server_account(&self) -> Option
; - - /// List of keys available for the account - fn available_keys(&self, block: BlockId, account: &Address) -> Option>; - - /// Update permissioning contract - fn update_acl_contract(&self); -} - -/// Secret Store keys provider -pub struct SecretStoreKeys -where - C: CallContract + RegistryInfo + Send + Sync + 'static, -{ - client: Arc, - key_server_account: Option
, - keys_acl_contract: RwLock>, -} - -impl SecretStoreKeys -where - C: CallContract + RegistryInfo + Send + Sync + 'static, -{ - /// Create provider - pub fn new(client: Arc, key_server_account: Option
) -> Self { - SecretStoreKeys { - client, - key_server_account, - keys_acl_contract: RwLock::new(None), - } - } -} - -impl KeyProvider for SecretStoreKeys -where - C: CallContract + RegistryInfo + Send + Sync + 'static, -{ - fn key_server_account(&self) -> Option
{ - self.key_server_account - } - - fn available_keys(&self, block: BlockId, account: &Address) -> Option> { - match *self.keys_acl_contract.read() { - Some(acl_contract_address) => { - let (data, decoder) = keys_acl_contract::functions::available_keys::call(*account); - if let Ok(value) = self.client.call_contract(block, acl_contract_address, data) { - decoder - .decode(&value) - .ok() - .map(|key_values| key_values.iter().map(key_to_address).collect()) - } else { - None - } - } - None => None, - } - } - - fn update_acl_contract(&self) { - let contract_address = self - .client - .registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.into(), BlockId::Latest); - if *self.keys_acl_contract.read() != contract_address { - trace!(target: "privatetx", "Configuring for ACL checker contract from address {:?}", - contract_address); - *self.keys_acl_contract.write() = contract_address; - } - } -} - -/// Dummy keys provider. -pub struct StoringKeyProvider { - available_keys: RwLock>>, - key_server_account: Option
, -} - -impl StoringKeyProvider { - /// Store available keys - pub fn set_available_keys(&self, keys: &Vec
) { - *self.available_keys.write() = Some(keys.clone()) - } -} - -impl Default for StoringKeyProvider { - fn default() -> Self { - StoringKeyProvider { - available_keys: RwLock::new(None), - key_server_account: Some(Address::default()), - } - } -} - -impl KeyProvider for StoringKeyProvider { - fn key_server_account(&self) -> Option
{ - self.key_server_account - } - - fn available_keys(&self, _block: BlockId, _account: &Address) -> Option> { - self.available_keys.read().clone() - } - - fn update_acl_contract(&self) {} -} - -#[cfg(test)] -mod tests { - use super::*; - use bytes::Bytes; - use ethkey::{KeyPair, Secret}; - use std::sync::Arc; - - struct DummyRegistryClient { - registry_address: Option
, - } - - impl DummyRegistryClient { - pub fn new(registry_address: Option
) -> Self { - DummyRegistryClient { registry_address } - } - } - - impl RegistryInfo for DummyRegistryClient { - fn registry_address(&self, _name: String, _block: BlockId) -> Option
{ - self.registry_address - } - } - - impl CallContract for DummyRegistryClient { - fn call_contract( - &self, - _id: BlockId, - _address: Address, - _data: Bytes, - ) -> Result { - Ok(vec![]) - } - } - - #[test] - fn should_update_acl_contract() { - let key = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000011", - )) - .unwrap(); - let client = DummyRegistryClient::new(Some(key.address())); - let keys_data = SecretStoreKeys::new(Arc::new(client), None); - keys_data.update_acl_contract(); - assert_eq!(keys_data.keys_acl_contract.read().unwrap(), key.address()); - } -} diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs deleted file mode 100644 index 44fdad512..000000000 --- a/ethcore/private-tx/src/lib.rs +++ /dev/null @@ -1,1004 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -//! Private transactions module. - -// Recursion limit required because of -// error_chain foreign_links. -#![recursion_limit = "256"] - -mod encryptor; -mod error; -mod key_server_keys; -mod messages; -mod private_transactions; - -extern crate common_types as types; -extern crate ethabi; -extern crate ethcore; -extern crate ethcore_call_contract as call_contract; -extern crate ethcore_io as io; -extern crate ethcore_miner; -extern crate ethereum_types; -extern crate ethjson; -extern crate ethkey; -extern crate fetch; -extern crate futures; -extern crate heapsize; -extern crate keccak_hash as hash; -extern crate parity_bytes as bytes; -extern crate parity_crypto as crypto; -extern crate parking_lot; -extern crate patricia_trie_ethereum as ethtrie; -extern crate rlp; -extern crate rustc_hex; -extern crate transaction_pool as txpool; -extern crate trie_db as trie; -extern crate url; -#[macro_use] -extern crate log; -#[macro_use] -extern crate ethabi_derive; -#[macro_use] -extern crate ethabi_contract; -extern crate derive_more; -#[macro_use] -extern crate rlp_derive; - -#[cfg(test)] -extern crate env_logger; -#[cfg(test)] -extern crate rand; - -pub use encryptor::{Encryptor, EncryptorConfig, NoopEncryptor, SecretStoreEncryptor}; -pub use error::Error; -pub use key_server_keys::{KeyProvider, SecretStoreKeys, StoringKeyProvider}; -pub use messages::{PrivateTransaction, SignedPrivateTransaction}; -pub use private_transactions::{ - PrivateTransactionSigningDesc, SigningStore, VerificationStore, VerifiedPrivateTransaction, -}; - -use bytes::Bytes; -use call_contract::CallContract; -use ethabi::FunctionOutputDecoder; -use ethcore::{ - client::{ - BlockId, BlockInfo, Call, ChainMessageType, ChainNotify, Client, ClientIoMessage, NewBlocks, - }, - contract_address as ethcore_contract_address, - executed::Executed, - executive::{Executive, TransactOptions}, - miner::{self, pool_client::NonceCache, Miner, MinerService}, - state, state_db, - trace::{Tracer, VMTracer}, -}; -use ethereum_types::{Address, H128, H256, U256}; -use ethkey::{public_to_address, recover, Signature}; -use hash::keccak; -use io::IoChannel; -use parking_lot::RwLock; -use rlp::*; -use rustc_hex::FromHex; -use std::{ - collections::{BTreeMap, HashMap, HashSet}, - sync::{Arc, Weak}, -}; -use types::transaction::{Action, SignedTransaction, Transaction, UnverifiedTransaction}; - -// Source avaiable at https://github.com/parity-contracts/private-tx/blob/master/contracts/PrivateContract.sol -const DEFAULT_STUB_CONTRACT: &'static str = include_str!("../res/private.evm"); - -use_contract!(private_contract, "res/private.json"); - -/// Initialization vector length. -const INIT_VEC_LEN: usize = 16; - -/// Size of nonce cache -const NONCE_CACHE_SIZE: usize = 128; - -/// Version for the initial private contract wrapper -const INITIAL_PRIVATE_CONTRACT_VER: usize = 1; - -/// Version for the private contract notification about private state changes added -const PRIVATE_CONTRACT_WITH_NOTIFICATION_VER: usize = 2; - -/// Configurtion for private transaction provider -#[derive(Default, PartialEq, Debug, Clone)] -pub struct ProviderConfig { - /// Accounts that can be used for validation - pub validator_accounts: Vec
, - /// Account used for signing public transactions created from private transactions - pub signer_account: Option
, -} - -#[derive(Debug)] -/// Private transaction execution receipt. -pub struct Receipt { - /// Private transaction hash. - pub hash: H256, - /// Contract address. - pub contract_address: Address, - /// Execution status. - pub status_code: u8, -} - -/// Payload signing and decrypting capabilities. -pub trait Signer: Send + Sync { - /// Decrypt payload using private key of given address. - fn decrypt( - &self, - account: Address, - shared_mac: &[u8], - payload: &[u8], - ) -> Result, Error>; - /// Sign given hash using provided account. - fn sign(&self, account: Address, hash: ethkey::Message) -> Result; -} - -/// Signer implementation that errors on any request. -pub struct DummySigner; -impl Signer for DummySigner { - fn decrypt( - &self, - _account: Address, - _shared_mac: &[u8], - _payload: &[u8], - ) -> Result, Error> { - Err("Decrypting is not supported.".to_owned())? - } - - fn sign(&self, _account: Address, _hash: ethkey::Message) -> Result { - Err("Signing is not supported.".to_owned())? - } -} - -/// Signer implementation using multiple keypairs -pub struct KeyPairSigner(pub Vec); -impl Signer for KeyPairSigner { - fn decrypt( - &self, - account: Address, - shared_mac: &[u8], - payload: &[u8], - ) -> Result, Error> { - let kp = self - .0 - .iter() - .find(|k| k.address() == account) - .ok_or(ethkey::Error::InvalidAddress)?; - Ok(ethkey::crypto::ecies::decrypt( - kp.secret(), - shared_mac, - payload, - )?) - } - - fn sign(&self, account: Address, hash: ethkey::Message) -> Result { - let kp = self - .0 - .iter() - .find(|k| k.address() == account) - .ok_or(ethkey::Error::InvalidAddress)?; - Ok(ethkey::sign(kp.secret(), &hash)?) - } -} - -/// Manager of private transactions -pub struct Provider { - encryptor: Box, - validator_accounts: HashSet
, - signer_account: Option
, - notify: RwLock>>, - transactions_for_signing: RwLock, - transactions_for_verification: VerificationStore, - client: Arc, - miner: Arc, - accounts: Arc, - channel: IoChannel, - keys_provider: Arc, -} - -#[derive(Debug)] -pub struct PrivateExecutionResult -where - T: Tracer, - V: VMTracer, -{ - code: Option, - state: Bytes, - contract_address: Address, - result: Executed, -} - -impl Provider { - /// Create a new provider. - pub fn new( - client: Arc, - miner: Arc, - accounts: Arc, - encryptor: Box, - config: ProviderConfig, - channel: IoChannel, - keys_provider: Arc, - ) -> Self { - keys_provider.update_acl_contract(); - Provider { - encryptor, - validator_accounts: config.validator_accounts.into_iter().collect(), - signer_account: config.signer_account, - notify: RwLock::default(), - transactions_for_signing: RwLock::default(), - transactions_for_verification: VerificationStore::default(), - client, - miner, - accounts, - channel, - keys_provider, - } - } - - // TODO [ToDr] Don't use `ChainNotify` here! - // Better to create a separate notification type for this. - /// Adds an actor to be notified on certain events - pub fn add_notify(&self, target: Arc) { - self.notify.write().push(Arc::downgrade(&target)); - } - - fn notify(&self, f: F) - where - F: Fn(&dyn ChainNotify), - { - for np in self.notify.read().iter() { - if let Some(n) = np.upgrade() { - f(&*n); - } - } - } - - /// 1. Create private transaction from the signed transaction - /// 2. Executes private transaction - /// 3. Save it with state returned on prev step to the queue for signing - /// 4. Broadcast corresponding message to the chain - pub fn create_private_transaction( - &self, - signed_transaction: SignedTransaction, - ) -> Result { - trace!(target: "privatetx", "Creating private transaction from regular transaction: {:?}", signed_transaction); - if self.signer_account.is_none() { - warn!(target: "privatetx", "Signing account not set"); - return Err(Error::SignerAccountNotSet); - } - let tx_hash = signed_transaction.hash(); - let contract = Self::contract_address_from_transaction(&signed_transaction) - .map_err(|_| Error::BadTransactionType)?; - let data = signed_transaction.rlp_bytes(); - let encrypted_transaction = self.encrypt( - &contract, - &Self::iv_from_transaction(&signed_transaction), - &data, - )?; - let private = PrivateTransaction::new(encrypted_transaction, contract); - // TODO #9825 [ToDr] Using BlockId::Latest is bad here, - // the block may change in the middle of execution - // causing really weird stuff to happen. - // We should retrieve hash and stick to that. IMHO - // best would be to change the API and only allow H256 instead of BlockID - // in private-tx to avoid such mistakes. - let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest)?; - let private_state = - self.execute_private_transaction(BlockId::Latest, &signed_transaction)?; - trace!(target: "privatetx", "Private transaction created, encrypted transaction: {:?}, private state: {:?}", private, private_state); - let contract_validators = self.get_validators(BlockId::Latest, &contract)?; - trace!(target: "privatetx", "Required validators: {:?}", contract_validators); - let private_state_hash = self.calculate_state_hash(&private_state, contract_nonce); - trace!(target: "privatetx", "Hashed effective private state for sender: {:?}", private_state_hash); - self.transactions_for_signing.write().add_transaction( - private.hash(), - signed_transaction, - contract_validators, - private_state, - contract_nonce, - )?; - self.broadcast_private_transaction(private.hash(), private.rlp_bytes()); - Ok(Receipt { - hash: tx_hash, - contract_address: contract, - status_code: 0, - }) - } - - /// Calculate hash from united private state and contract nonce - pub fn calculate_state_hash(&self, state: &Bytes, nonce: U256) -> H256 { - let state_hash = keccak(state); - let mut state_buf = [0u8; 64]; - state_buf[..32].clone_from_slice(&state_hash); - state_buf[32..].clone_from_slice(&H256::from(nonce)); - keccak(AsRef::<[u8]>::as_ref(&state_buf[..])) - } - - fn pool_client<'a>( - &'a self, - nonce_cache: &'a NonceCache, - local_accounts: &'a HashSet
, - ) -> miner::pool_client::PoolClient<'a, Client> { - let engine = self.client.engine(); - miner::pool_client::PoolClient::new( - &*self.client, - nonce_cache, - engine, - local_accounts, - None, // refuse_service_transactions = true - ) - } - - /// Retrieve and verify the first available private transaction for every sender - fn process_verification_queue(&self) -> Result<(), Error> { - let process_transaction = |transaction: &VerifiedPrivateTransaction| -> Result<_, String> { - let private_hash = transaction.private_transaction.hash(); - match transaction.validator_account { - None => { - trace!(target: "privatetx", "Propagating transaction further"); - self.broadcast_private_transaction( - private_hash, - transaction.private_transaction.rlp_bytes(), - ); - return Ok(()); - } - Some(validator_account) => { - if !self.validator_accounts.contains(&validator_account) { - trace!(target: "privatetx", "Propagating transaction further"); - self.broadcast_private_transaction( - private_hash, - transaction.private_transaction.rlp_bytes(), - ); - return Ok(()); - } - let contract = - Self::contract_address_from_transaction(&transaction.transaction) - .map_err(|_| "Incorrect type of action for the transaction")?; - // TODO #9825 [ToDr] Usage of BlockId::Latest - let contract_nonce = self.get_contract_nonce(&contract, BlockId::Latest); - if let Err(e) = contract_nonce { - return Err(format!("Cannot retrieve contract nonce: {:?}", e).into()); - } - let contract_nonce = contract_nonce.expect("Error was checked before"); - let private_state = - self.execute_private_transaction(BlockId::Latest, &transaction.transaction); - if let Err(e) = private_state { - return Err(format!("Cannot retrieve private state: {:?}", e).into()); - } - let private_state = private_state.expect("Error was checked before"); - let private_state_hash = - self.calculate_state_hash(&private_state, contract_nonce); - trace!(target: "privatetx", "Hashed effective private state for validator: {:?}", private_state_hash); - let signed_state = self.accounts.sign(validator_account, private_state_hash); - if let Err(e) = signed_state { - return Err(format!("Cannot sign the state: {:?}", e).into()); - } - let signed_state = signed_state.expect("Error was checked before"); - let signed_private_transaction = - SignedPrivateTransaction::new(private_hash, signed_state, None); - trace!(target: "privatetx", "Sending signature for private transaction: {:?}", signed_private_transaction); - self.broadcast_signed_private_transaction( - signed_private_transaction.hash(), - signed_private_transaction.rlp_bytes(), - ); - } - } - Ok(()) - }; - let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE); - let local_accounts = HashSet::new(); - let ready_transactions = self - .transactions_for_verification - .drain(self.pool_client(&nonce_cache, &local_accounts)); - for transaction in ready_transactions { - if let Err(e) = process_transaction(&transaction) { - warn!(target: "privatetx", "Error: {:?}", e); - } - } - Ok(()) - } - - /// Add signed private transaction into the store - /// Creates corresponding public transaction if last required signature collected and sends it to the chain - pub fn process_signature(&self, signed_tx: &SignedPrivateTransaction) -> Result<(), Error> { - trace!(target: "privatetx", "Processing signed private transaction"); - let private_hash = signed_tx.private_transaction_hash(); - let desc = match self.transactions_for_signing.read().get(&private_hash) { - None => { - // Not our transaction, broadcast further to peers - self.broadcast_signed_private_transaction(signed_tx.hash(), signed_tx.rlp_bytes()); - return Ok(()); - } - Some(desc) => desc, - }; - let last = self.last_required_signature(&desc, signed_tx.signature())?; - - if last { - let mut signatures = desc.received_signatures.clone(); - signatures.push(signed_tx.signature()); - let rsv: Vec = signatures - .into_iter() - .map(|sign| sign.into_electrum().into()) - .collect(); - // Create public transaction - let signer_account = self - .signer_account - .ok_or_else(|| Error::SignerAccountNotSet)?; - let state = self - .client - .state_at(BlockId::Latest) - .ok_or(Error::StatePruned)?; - let nonce = state.nonce(&signer_account)?; - let public_tx = self.public_transaction( - desc.state.clone(), - &desc.original_transaction, - &rsv, - nonce, - desc.original_transaction.gas_price, - )?; - trace!(target: "privatetx", "Last required signature received, public transaction created: {:?}", public_tx); - // Sign and add it to the queue - let chain_id = desc.original_transaction.chain_id(); - let hash = public_tx.hash(chain_id); - let signature = self.accounts.sign(signer_account, hash)?; - let signed = SignedTransaction::new(public_tx.with_signature(signature, chain_id))?; - match self - .miner - .import_own_transaction(&*self.client, signed.into()) - { - Ok(_) => trace!(target: "privatetx", "Public transaction added to queue"), - Err(err) => { - warn!(target: "privatetx", "Failed to add transaction to queue, error: {:?}", err); - return Err(err.into()); - } - } - // Notify about state changes - let contract = Self::contract_address_from_transaction(&desc.original_transaction)?; - // TODO #9825 Usage of BlockId::Latest - if self.get_contract_version(BlockId::Latest, &contract) - >= PRIVATE_CONTRACT_WITH_NOTIFICATION_VER - { - match self.state_changes_notify( - BlockId::Latest, - &contract, - &desc.original_transaction.sender(), - desc.original_transaction.hash(), - ) { - Ok(_) => { - trace!(target: "privatetx", "Notification about private state changes sent") - } - Err(err) => { - warn!(target: "privatetx", "Failed to send private state changed notification, error: {:?}", err) - } - } - } - // Remove from store for signing - if let Err(err) = self.transactions_for_signing.write().remove(&private_hash) { - warn!(target: "privatetx", "Failed to remove transaction from signing store, error: {:?}", err); - return Err(err); - } - } else { - // Add signature to the store - match self - .transactions_for_signing - .write() - .add_signature(&private_hash, signed_tx.signature()) - { - Ok(_) => trace!(target: "privatetx", "Signature stored for private transaction"), - Err(err) => { - warn!(target: "privatetx", "Failed to add signature to signing store, error: {:?}", err); - return Err(err); - } - } - } - Ok(()) - } - - fn contract_address_from_transaction( - transaction: &SignedTransaction, - ) -> Result { - match transaction.action { - Action::Call(contract) => Ok(contract), - _ => { - warn!(target: "privatetx", "Incorrect type of action for the transaction"); - return Err(Error::BadTransactionType); - } - } - } - - fn last_required_signature( - &self, - desc: &PrivateTransactionSigningDesc, - sign: Signature, - ) -> Result { - if desc.received_signatures.contains(&sign) { - return Ok(false); - } - let state_hash = self.calculate_state_hash(&desc.state, desc.contract_nonce); - match recover(&sign, &state_hash) { - Ok(public) => { - let sender = public_to_address(&public); - match desc.validators.contains(&sender) { - true => Ok(desc.received_signatures.len() + 1 == desc.validators.len()), - false => { - warn!(target: "privatetx", "Sender's state doesn't correspond to validator's"); - return Err(Error::StateIncorrect); - } - } - } - Err(err) => { - warn!(target: "privatetx", "Sender's state doesn't correspond to validator's, error {:?}", err); - return Err(err.into()); - } - } - } - - /// Broadcast the private transaction message to the chain - fn broadcast_private_transaction(&self, transaction_hash: H256, message: Bytes) { - self.notify(|notify| { - notify.broadcast(ChainMessageType::PrivateTransaction( - transaction_hash, - message.clone(), - )) - }); - } - - /// Broadcast signed private transaction message to the chain - fn broadcast_signed_private_transaction(&self, transaction_hash: H256, message: Bytes) { - self.notify(|notify| { - notify.broadcast(ChainMessageType::SignedPrivateTransaction( - transaction_hash, - message.clone(), - )) - }); - } - - fn iv_from_transaction(transaction: &SignedTransaction) -> H128 { - let nonce = keccak(&transaction.nonce.rlp_bytes()); - let (iv, _) = nonce.split_at(INIT_VEC_LEN); - H128::from_slice(iv) - } - - fn iv_from_address(contract_address: &Address) -> H128 { - let address = keccak(&contract_address.rlp_bytes()); - let (iv, _) = address.split_at(INIT_VEC_LEN); - H128::from_slice(iv) - } - - fn encrypt( - &self, - contract_address: &Address, - initialisation_vector: &H128, - data: &[u8], - ) -> Result { - trace!(target: "privatetx", "Encrypt data using key(address): {:?}", contract_address); - Ok(self - .encryptor - .encrypt(contract_address, initialisation_vector, data)?) - } - - fn decrypt(&self, contract_address: &Address, data: &[u8]) -> Result { - trace!(target: "privatetx", "Decrypt data using key(address): {:?}", contract_address); - Ok(self.encryptor.decrypt(contract_address, data)?) - } - - fn get_decrypted_state(&self, address: &Address, block: BlockId) -> Result { - let (data, decoder) = private_contract::functions::state::call(); - let value = self.client.call_contract(block, *address, data)?; - let state = decoder - .decode(&value) - .map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?; - self.decrypt(address, &state) - } - - fn get_decrypted_code(&self, address: &Address, block: BlockId) -> Result { - let (data, decoder) = private_contract::functions::code::call(); - let value = self.client.call_contract(block, *address, data)?; - let state = decoder - .decode(&value) - .map_err(|e| Error::Call(format!("Contract call failed {:?}", e)))?; - self.decrypt(address, &state) - } - - pub fn get_contract_nonce(&self, address: &Address, block: BlockId) -> Result { - let (data, decoder) = private_contract::functions::nonce::call(); - let value = self.client.call_contract(block, *address, data)?; - decoder - .decode(&value) - .map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into()) - } - - fn snapshot_to_storage(raw: Bytes) -> HashMap { - let items = raw.len() / 64; - (0..items) - .map(|i| { - let offset = i * 64; - let key = H256::from_slice(&raw[offset..(offset + 32)]); - let value = H256::from_slice(&raw[(offset + 32)..(offset + 64)]); - (key, value) - }) - .collect() - } - - fn snapshot_from_storage(storage: &HashMap) -> Bytes { - let mut raw = Vec::with_capacity(storage.len() * 64); - // Sort the storage to guarantee the order for all parties - let sorted_storage: BTreeMap<&H256, &H256> = storage.iter().collect(); - for (key, value) in sorted_storage { - raw.extend_from_slice(key); - raw.extend_from_slice(value); - } - raw - } - - fn patch_account_state( - &self, - contract_address: &Address, - block: BlockId, - state: &mut state::State, - ) -> Result<(), Error> { - let contract_code = Arc::new(self.get_decrypted_code(contract_address, block)?); - let contract_state = self.get_decrypted_state(contract_address, block)?; - trace!(target: "privatetx", "Patching contract at {:?}, code: {:?}, state: {:?}", contract_address, contract_code, contract_state); - state.patch_account( - contract_address, - contract_code, - Self::snapshot_to_storage(contract_state), - )?; - Ok(()) - } - - pub fn execute_private( - &self, - transaction: &SignedTransaction, - options: TransactOptions, - block: BlockId, - ) -> Result, Error> - where - T: Tracer, - V: VMTracer, - { - let mut env_info = self.client.env_info(block).ok_or(Error::StatePruned)?; - env_info.gas_limit = transaction.gas; - - let mut state = self.client.state_at(block).ok_or(Error::StatePruned)?; - // TODO #9825 in case of BlockId::Latest these need to operate on the same state - let contract_address = match transaction.action { - Action::Call(ref contract_address) => { - // Patch current contract state - self.patch_account_state(contract_address, block, &mut state)?; - Some(*contract_address) - } - Action::Create => None, - }; - - let engine = self.client.engine(); - let sender = transaction.sender(); - let nonce = state.nonce(&sender)?; - let contract_address = contract_address.unwrap_or_else(|| { - let (new_address, _) = ethcore_contract_address( - engine.create_address_scheme(env_info.number), - &sender, - &nonce, - &transaction.data, - ); - new_address - }); - // Patch other available private contracts' states as well - // TODO: #10133 patch only required for the contract states - if let Some(key_server_account) = self.keys_provider.key_server_account() { - if let Some(available_contracts) = self - .keys_provider - .available_keys(block, &key_server_account) - { - for private_contract in available_contracts { - if private_contract == contract_address { - continue; - } - self.patch_account_state(&private_contract, block, &mut state)?; - } - } - } - let machine = engine.machine(); - let schedule = machine.schedule(env_info.number); - let result = Executive::new(&mut state, &env_info, &machine, &schedule) - .transact_virtual(transaction, options)?; - let (encrypted_code, encrypted_storage) = { - let (code, storage) = state.into_account(&contract_address)?; - trace!(target: "privatetx", "Private contract executed. code: {:?}, state: {:?}, result: {:?}", code, storage, result.output); - let enc_code = match code { - Some(c) => Some(self.encrypt( - &contract_address, - &Self::iv_from_address(&contract_address), - &c, - )?), - None => None, - }; - ( - enc_code, - self.encrypt( - &contract_address, - &Self::iv_from_transaction(transaction), - &Self::snapshot_from_storage(&storage), - )?, - ) - }; - Ok(PrivateExecutionResult { - code: encrypted_code, - state: encrypted_storage, - contract_address: contract_address, - result, - }) - } - - fn generate_constructor(validators: &[Address], code: Bytes, storage: Bytes) -> Bytes { - let constructor_code = DEFAULT_STUB_CONTRACT - .from_hex() - .expect("Default contract code is valid"); - private_contract::constructor( - constructor_code, - validators.iter().map(|a| *a).collect::>(), - code, - storage, - ) - } - - fn generate_set_state_call(signatures: &[Signature], storage: Bytes) -> Bytes { - private_contract::functions::set_state::encode_input( - storage, - signatures - .iter() - .map(|s| { - let mut v: [u8; 32] = [0; 32]; - v[31] = s.v(); - v - }) - .collect::>(), - signatures.iter().map(|s| s.r()).collect::>(), - signatures.iter().map(|s| s.s()).collect::>(), - ) - } - - /// Returns the key from the key server associated with the contract - pub fn contract_key_id(&self, contract_address: &Address) -> Result { - Ok(key_server_keys::address_to_key(contract_address)) - } - - /// Create encrypted public contract deployment transaction. - pub fn public_creation_transaction( - &self, - block: BlockId, - source: &SignedTransaction, - validators: &[Address], - gas_price: U256, - ) -> Result<(Transaction, Address), Error> { - if let Action::Call(_) = source.action { - return Err(Error::BadTransactionType); - } - let sender = source.sender(); - let state = self.client.state_at(block).ok_or(Error::StatePruned)?; - let nonce = state.nonce(&sender)?; - let executed = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; - let header = self - .client - .block_header(block) - .ok_or(Error::StatePruned) - .and_then(|h| h.decode().map_err(|_| Error::StateIncorrect).into())?; - let (executed_code, executed_state) = (executed.code.unwrap_or_default(), executed.state); - let tx_data = - Self::generate_constructor(validators, executed_code.clone(), executed_state.clone()); - let mut tx = Transaction { - nonce: nonce, - action: Action::Create, - gas: u64::max_value().into(), - gas_price: gas_price, - value: source.value, - data: tx_data, - }; - tx.gas = match self - .client - .estimate_gas(&tx.clone().fake_sign(sender), &state, &header) - { - Ok(estimated_gas) => estimated_gas, - Err(_) => self.estimate_tx_gas(validators, &executed_code, &executed_state, &[]), - }; - - Ok((tx, executed.contract_address)) - } - - fn estimate_tx_gas( - &self, - validators: &[Address], - code: &Bytes, - state: &Bytes, - signatures: &[Signature], - ) -> U256 { - let default_gas = 650000 - + validators.len() as u64 * 30000 - + code.len() as u64 * 8000 - + signatures.len() as u64 * 50000 - + state.len() as u64 * 8000; - default_gas.into() - } - - /// Create encrypted public contract deployment transaction. Returns updated encrypted state. - pub fn execute_private_transaction( - &self, - block: BlockId, - source: &SignedTransaction, - ) -> Result { - if let Action::Create = source.action { - return Err(Error::BadTransactionType); - } - let result = self.execute_private(source, TransactOptions::with_no_tracing(), block)?; - Ok(result.state) - } - - /// Create encrypted public transaction from private transaction. - pub fn public_transaction( - &self, - state: Bytes, - source: &SignedTransaction, - signatures: &[Signature], - nonce: U256, - gas_price: U256, - ) -> Result { - let gas = self.estimate_tx_gas(&[], &Vec::new(), &state, signatures); - Ok(Transaction { - nonce: nonce, - action: source.action.clone(), - gas: gas.into(), - gas_price: gas_price, - value: 0.into(), - data: Self::generate_set_state_call(signatures, state), - }) - } - - /// Call into private contract. - pub fn private_call( - &self, - block: BlockId, - transaction: &SignedTransaction, - ) -> Result { - let result = - self.execute_private(transaction, TransactOptions::with_no_tracing(), block)?; - Ok(result.result) - } - - /// Returns private validators for a contract. - pub fn get_validators(&self, block: BlockId, address: &Address) -> Result, Error> { - let (data, decoder) = private_contract::functions::get_validators::call(); - let value = self.client.call_contract(block, *address, data)?; - decoder - .decode(&value) - .map_err(|e| Error::Call(format!("Contract call failed {:?}", e)).into()) - } - - fn get_contract_version(&self, block: BlockId, address: &Address) -> usize { - let (data, decoder) = private_contract::functions::get_version::call(); - match self - .client - .call_contract(block, *address, data) - .and_then(|value| decoder.decode(&value).map_err(|e| e.to_string())) - { - Ok(version) => version.low_u64() as usize, - Err(_) => INITIAL_PRIVATE_CONTRACT_VER, - } - } - - fn state_changes_notify( - &self, - block: BlockId, - address: &Address, - originator: &Address, - transaction_hash: H256, - ) -> Result<(), Error> { - let (data, _) = private_contract::functions::notify_changes::call( - *originator, - transaction_hash.0.to_vec(), - ); - let _value = self.client.call_contract(block, *address, data)?; - Ok(()) - } -} - -pub trait Importer { - /// Process received private transaction - fn import_private_transaction(&self, _rlp: &[u8]) -> Result; - - /// Add signed private transaction into the store - /// - /// Creates corresponding public transaction if last required signature collected and sends it to the chain - fn import_signed_private_transaction(&self, _rlp: &[u8]) -> Result; -} - -// TODO [ToDr] Offload more heavy stuff to the IoService thread. -// It seems that a lot of heavy work (verification) is done in this thread anyway -// it might actually make sense to decouple it from clientService and just use dedicated thread -// for both verification and execution. - -impl Importer for Arc { - fn import_private_transaction(&self, rlp: &[u8]) -> Result { - trace!(target: "privatetx", "Private transaction received"); - let private_tx: PrivateTransaction = Rlp::new(rlp).as_val()?; - let private_tx_hash = private_tx.hash(); - let contract = private_tx.contract(); - let contract_validators = self.get_validators(BlockId::Latest, &contract)?; - - let validation_account = contract_validators - .iter() - .find(|address| self.validator_accounts.contains(address)); - - // Extract the original transaction - let encrypted_data = private_tx.encrypted(); - let transaction_bytes = self.decrypt(&contract, &encrypted_data)?; - let original_tx: UnverifiedTransaction = Rlp::new(&transaction_bytes).as_val()?; - let nonce_cache = NonceCache::new(NONCE_CACHE_SIZE); - let local_accounts = HashSet::new(); - // Add to the queue for further verification - self.transactions_for_verification.add_transaction( - original_tx, - validation_account.map(|&account| account), - private_tx, - self.pool_client(&nonce_cache, &local_accounts), - )?; - let provider = Arc::downgrade(self); - let result = self.channel.send(ClientIoMessage::execute(move |_| { - if let Some(provider) = provider.upgrade() { - if let Err(e) = provider.process_verification_queue() { - warn!(target: "privatetx", "Unable to process the queue: {}", e); - } - } - })); - if let Err(e) = result { - warn!(target: "privatetx", "Error sending NewPrivateTransaction message: {:?}", e); - } - Ok(private_tx_hash) - } - - fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result { - let tx: SignedPrivateTransaction = Rlp::new(rlp).as_val()?; - trace!(target: "privatetx", "Signature for private transaction received: {:?}", tx); - let private_hash = tx.private_transaction_hash(); - let provider = Arc::downgrade(self); - let result = self.channel.send(ClientIoMessage::execute(move |_| { - if let Some(provider) = provider.upgrade() { - if let Err(e) = provider.process_signature(&tx) { - warn!(target: "privatetx", "Unable to process the signature: {}", e); - } - } - })); - if let Err(e) = result { - warn!(target: "privatetx", "Error sending NewSignedPrivateTransaction message: {:?}", e); - } - Ok(private_hash) - } -} - -impl ChainNotify for Provider { - fn new_blocks(&self, new_blocks: NewBlocks) { - if new_blocks.imported.is_empty() || new_blocks.has_more_blocks_to_import { - return; - } - trace!(target: "privatetx", "New blocks imported, try to prune the queue"); - if let Err(err) = self.process_verification_queue() { - warn!(target: "privatetx", "Cannot prune private transactions queue. error: {:?}", err); - } - self.keys_provider.update_acl_contract(); - } -} diff --git a/ethcore/private-tx/src/messages.rs b/ethcore/private-tx/src/messages.rs deleted file mode 100644 index 0953565de..000000000 --- a/ethcore/private-tx/src/messages.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -use bytes::Bytes; -use ethereum_types::{Address, H256, U256}; -use ethkey::Signature; -use hash::keccak; -use rlp::Encodable; -use types::transaction::signature::{add_chain_replay_protection, check_replay_protection}; - -/// Message with private transaction encrypted -#[derive(Default, Debug, Clone, PartialEq, RlpEncodable, RlpDecodable, Eq)] -pub struct PrivateTransaction { - /// Encrypted data - encrypted: Bytes, - /// Address of the contract - contract: Address, - /// Hash - hash: H256, -} - -impl PrivateTransaction { - /// Constructor - pub fn new(encrypted: Bytes, contract: Address) -> Self { - PrivateTransaction { - encrypted, - contract, - hash: 0.into(), - } - .compute_hash() - } - - fn compute_hash(mut self) -> PrivateTransaction { - self.hash = keccak(&*self.rlp_bytes()); - self - } - - /// Hash of the private transaction - pub fn hash(&self) -> H256 { - self.hash - } - - /// Address of the contract - pub fn contract(&self) -> Address { - self.contract - } - - /// Encrypted data - pub fn encrypted(&self) -> Bytes { - self.encrypted.clone() - } -} - -/// Message about private transaction's signing -#[derive(Default, Debug, Clone, PartialEq, RlpEncodable, RlpDecodable, Eq)] -pub struct SignedPrivateTransaction { - /// Hash of the corresponding private transaction - private_transaction_hash: H256, - /// Signature of the validator - /// The V field of the signature - v: u64, - /// The R field of the signature - r: U256, - /// The S field of the signature - s: U256, - /// Hash - hash: H256, -} - -impl SignedPrivateTransaction { - /// Construct a signed private transaction message - pub fn new(private_transaction_hash: H256, sig: Signature, chain_id: Option) -> Self { - SignedPrivateTransaction { - private_transaction_hash: private_transaction_hash, - r: sig.r().into(), - s: sig.s().into(), - v: add_chain_replay_protection(sig.v() as u64, chain_id), - hash: 0.into(), - } - .compute_hash() - } - - fn compute_hash(mut self) -> SignedPrivateTransaction { - self.hash = keccak(&*self.rlp_bytes()); - self - } - - pub fn standard_v(&self) -> u8 { - check_replay_protection(self.v) - } - - /// Construct a signature object from the sig. - pub fn signature(&self) -> Signature { - Signature::from_rsv(&self.r.into(), &self.s.into(), self.standard_v()) - } - - /// Get the hash of of the original transaction. - pub fn private_transaction_hash(&self) -> H256 { - self.private_transaction_hash - } - - /// Own hash - pub fn hash(&self) -> H256 { - self.hash - } -} diff --git a/ethcore/private-tx/src/private_transactions.rs b/ethcore/private-tx/src/private_transactions.rs deleted file mode 100644 index d20efcffe..000000000 --- a/ethcore/private-tx/src/private_transactions.rs +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -use std::{ - cmp, - collections::{HashMap, HashSet}, - sync::Arc, -}; - -use bytes::Bytes; -use error::Error; -use ethcore_miner::pool; -use ethereum_types::{Address, H256, U256}; -use ethkey::Signature; -use heapsize::HeapSizeOf; -use messages::PrivateTransaction; -use parking_lot::RwLock; -use txpool::{self, VerifiedTransaction, Verifier}; -use types::transaction::{SignedTransaction, UnverifiedTransaction}; - -type Pool = txpool::Pool; - -/// Maximum length for private transactions queues. -const MAX_QUEUE_LEN: usize = 8312; - -/// Private transaction stored in queue for verification -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct VerifiedPrivateTransaction { - /// Original private transaction - pub private_transaction: PrivateTransaction, - /// Address that should be used for verification - pub validator_account: Option
, - /// Resulting verified transaction - pub transaction: SignedTransaction, - /// Original transaction hash - pub transaction_hash: H256, - /// Original transaction sender - pub transaction_sender: Address, -} - -impl txpool::VerifiedTransaction for VerifiedPrivateTransaction { - type Hash = H256; - type Sender = Address; - - fn hash(&self) -> &H256 { - &self.transaction_hash - } - - fn mem_usage(&self) -> usize { - self.transaction.heap_size_of_children() - } - - fn sender(&self) -> &Address { - &self.transaction_sender - } -} - -impl pool::ScoredTransaction for VerifiedPrivateTransaction { - fn priority(&self) -> pool::Priority { - pool::Priority::Regular - } - - /// Gets transaction gas price. - fn gas_price(&self) -> &U256 { - &self.transaction.gas_price - } - - /// Gets transaction nonce. - fn nonce(&self) -> U256 { - self.transaction.nonce - } -} - -/// Checks readiness of transactions by looking if the transaction from sender already exists. -/// Guarantees only one transaction per sender -#[derive(Debug)] -pub struct PrivateReadyState { - senders: HashSet
, - state: C, -} - -impl PrivateReadyState { - /// Create new State checker, given client interface. - pub fn new(state: C) -> Self { - PrivateReadyState { - senders: Default::default(), - state, - } - } -} - -impl txpool::Ready - for PrivateReadyState -{ - fn is_ready(&mut self, tx: &VerifiedPrivateTransaction) -> txpool::Readiness { - let sender = tx.sender(); - let state = &self.state; - let state_nonce = state.account_nonce(sender); - if self.senders.contains(sender) { - txpool::Readiness::Future - } else { - self.senders.insert(*sender); - match tx.transaction.nonce.cmp(&state_nonce) { - cmp::Ordering::Greater => txpool::Readiness::Future, - cmp::Ordering::Less => txpool::Readiness::Stale, - cmp::Ordering::Equal => txpool::Readiness::Ready, - } - } - } -} - -/// Storage for private transactions for verification -pub struct VerificationStore { - verification_pool: RwLock, - verification_options: pool::verifier::Options, -} - -impl Default for VerificationStore { - fn default() -> Self { - VerificationStore { - verification_pool: RwLock::new(txpool::Pool::new( - txpool::NoopListener, - pool::scoring::NonceAndGasPrice(pool::PrioritizationStrategy::GasPriceOnly), - pool::Options { - max_count: MAX_QUEUE_LEN, - max_per_sender: MAX_QUEUE_LEN / 10, - max_mem_usage: 8 * 1024 * 1024, - }, - )), - verification_options: pool::verifier::Options { - // TODO [ToDr] This should probably be based on some real values? - minimal_gas_price: 0.into(), - block_gas_limit: 8_000_000.into(), - tx_gas_limit: U256::max_value(), - no_early_reject: false, - }, - } - } -} - -impl VerificationStore { - /// Adds private transaction for verification into the store - pub fn add_transaction( - &self, - transaction: UnverifiedTransaction, - validator_account: Option
, - private_transaction: PrivateTransaction, - client: C, - ) -> Result<(), Error> { - let options = self.verification_options.clone(); - // Use pool's verifying pipeline for original transaction's verification - let verifier = - pool::verifier::Verifier::new(client.clone(), options, Default::default(), None); - let unverified = pool::verifier::Transaction::Unverified(transaction); - let verified_tx = verifier.verify_transaction(unverified)?; - let signed_tx: SignedTransaction = verified_tx.signed().clone(); - let signed_hash = signed_tx.hash(); - let signed_sender = signed_tx.sender(); - let verified = VerifiedPrivateTransaction { - private_transaction, - validator_account, - transaction: signed_tx, - transaction_hash: signed_hash, - transaction_sender: signed_sender, - }; - let replace = pool::replace::ReplaceByScoreAndReadiness::new( - self.verification_pool.read().scoring().clone(), - client, - ); - self.verification_pool.write().import(verified, &replace)?; - Ok(()) - } - - /// Drains transactions ready for verification from the pool - /// Returns only one transaction per sender because several cannot be verified in a row without verification from other peers - pub fn drain( - &self, - client: C, - ) -> Vec> { - let ready = PrivateReadyState::new(client); - let transactions: Vec<_> = self.verification_pool.read().pending(ready).collect(); - let mut pool = self.verification_pool.write(); - for tx in &transactions { - pool.remove(tx.hash(), true); - } - transactions - } -} - -/// Desriptor for private transaction stored in queue for signing -#[derive(Debug, Clone)] -pub struct PrivateTransactionSigningDesc { - /// Original unsigned transaction - pub original_transaction: SignedTransaction, - /// Supposed validators from the contract - pub validators: Vec
, - /// Already obtained signatures - pub received_signatures: Vec, - /// State after transaction execution to compare further with received from validators - pub state: Bytes, - /// Build-in nonce of the contract - pub contract_nonce: U256, -} - -/// Storage for private transactions for signing -#[derive(Default)] -pub struct SigningStore { - /// Transactions and descriptors for signing - transactions: HashMap, -} - -impl SigningStore { - /// Adds new private transaction into the store for signing - pub fn add_transaction( - &mut self, - private_hash: H256, - transaction: SignedTransaction, - validators: Vec
, - state: Bytes, - contract_nonce: U256, - ) -> Result<(), Error> { - if self.transactions.len() > MAX_QUEUE_LEN { - return Err(Error::QueueIsFull); - } - - self.transactions.insert( - private_hash, - PrivateTransactionSigningDesc { - original_transaction: transaction.clone(), - validators: validators.clone(), - received_signatures: Vec::new(), - state, - contract_nonce, - }, - ); - Ok(()) - } - - /// Get copy of private transaction's description from the storage - pub fn get(&self, private_hash: &H256) -> Option { - self.transactions.get(private_hash).cloned() - } - - /// Removes desc from the store (after verification is completed) - pub fn remove(&mut self, private_hash: &H256) -> Result<(), Error> { - self.transactions.remove(private_hash); - Ok(()) - } - - /// Adds received signature for the stored private transaction - pub fn add_signature( - &mut self, - private_hash: &H256, - signature: Signature, - ) -> Result<(), Error> { - let desc = self - .transactions - .get_mut(private_hash) - .ok_or_else(|| Error::PrivateTransactionNotFound)?; - if !desc.received_signatures.contains(&signature) { - desc.received_signatures.push(signature); - } - Ok(()) - } -} diff --git a/ethcore/private-tx/tests/private_contract.rs b/ethcore/private-tx/tests/private_contract.rs deleted file mode 100644 index 23dc5d98d..000000000 --- a/ethcore/private-tx/tests/private_contract.rs +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -//! Contract for private transactions tests. - -extern crate common_types as types; -extern crate env_logger; -extern crate ethcore; -extern crate ethcore_io; -extern crate ethcore_private_tx; -extern crate ethkey; -extern crate keccak_hash as hash; -extern crate rustc_hex; - -#[macro_use] -extern crate log; - -use rustc_hex::{FromHex, ToHex}; -use std::sync::Arc; - -use ethcore::{ - client::BlockChainClient, - executive::contract_address, - miner::Miner, - test_helpers::{generate_dummy_client, push_block_with_transactions}, - CreateContractAddress, -}; -use ethkey::{KeyPair, Secret, Signature}; -use hash::keccak; -use types::{ - ids::BlockId, - transaction::{Action, Transaction}, -}; - -use ethcore_private_tx::{NoopEncryptor, Provider, ProviderConfig, StoringKeyProvider}; - -#[test] -fn private_contract() { - // This uses a simple private contract: contract Test1 { bytes32 public x; function setX(bytes32 _x) { x = _x; } } - let _ = ::env_logger::try_init(); - let client = generate_dummy_client(0); - let chain_id = client.signing_chain_id(); - let key1 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000011", - )) - .unwrap(); - let _key2 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000012", - )) - .unwrap(); - let key3 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000013", - )) - .unwrap(); - let key4 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000014", - )) - .unwrap(); - - let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![ - key1.clone(), - key3.clone(), - key4.clone(), - ])); - - let config = ProviderConfig { - validator_accounts: vec![key3.address(), key4.address()], - signer_account: None, - }; - - let io = ethcore_io::IoChannel::disconnected(); - let miner = Arc::new(Miner::new_for_tests( - &::ethcore::spec::Spec::new_test(), - None, - )); - let private_keys = Arc::new(StoringKeyProvider::default()); - let pm = Arc::new(Provider::new( - client.clone(), - miner, - signer.clone(), - Box::new(NoopEncryptor::default()), - config, - io, - private_keys, - )); - - let (address, _) = contract_address( - CreateContractAddress::FromSenderAndNonce, - &key1.address(), - &0.into(), - &[], - ); - - trace!("Creating private contract"); - let private_contract_test = "6060604052341561000f57600080fd5b60d88061001d6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c146046578063bc64b76d14607457600080fd5b3415605057600080fd5b60566098565b60405180826000191660001916815260200191505060405180910390f35b3415607e57600080fd5b6096600480803560001916906020019091905050609e565b005b60005481565b8060008160001916905550505600a165627a7a723058206acbdf4b15ca4c2d43e1b1879b830451a34f1e9d02ff1f2f394d8d857e79d2080029".from_hex().unwrap(); - let mut private_create_tx = Transaction::default(); - private_create_tx.action = Action::Create; - private_create_tx.data = private_contract_test; - private_create_tx.gas = 200000.into(); - let private_create_tx_signed = private_create_tx.sign(&key1.secret(), None); - let validators = vec![key3.address(), key4.address()]; - let (public_tx, _) = pm - .public_creation_transaction( - BlockId::Latest, - &private_create_tx_signed, - &validators, - 0.into(), - ) - .unwrap(); - let public_tx = public_tx.sign(&key1.secret(), chain_id); - trace!("Transaction created. Pushing block"); - push_block_with_transactions(&client, &[public_tx]); - - trace!("Querying default private state"); - let mut query_tx = Transaction::default(); - query_tx.action = Action::Call(address.clone()); - query_tx.data = "0c55699c".from_hex().unwrap(); // getX - query_tx.gas = 50000.into(); - query_tx.nonce = 1.into(); - let query_tx = query_tx.sign(&key1.secret(), chain_id); - let result = pm.private_call(BlockId::Latest, &query_tx).unwrap(); - assert_eq!( - &result.output[..], - &("0000000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap()[..]) - ); - assert_eq!( - pm.get_validators(BlockId::Latest, &address).unwrap(), - validators - ); - - trace!("Modifying private state"); - let mut private_tx = Transaction::default(); - private_tx.action = Action::Call(address.clone()); - private_tx.data = "bc64b76d2a00000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap(); //setX(42) - private_tx.gas = 120000.into(); - private_tx.nonce = 1.into(); - let private_tx = private_tx.sign(&key1.secret(), None); - let private_contract_nonce = pm.get_contract_nonce(&address, BlockId::Latest).unwrap(); - let private_state = pm - .execute_private_transaction(BlockId::Latest, &private_tx) - .unwrap(); - let nonced_state_hash = pm.calculate_state_hash(&private_state, private_contract_nonce); - let signatures: Vec<_> = [&key3, &key4] - .iter() - .map(|k| { - Signature::from( - ::ethkey::sign(&k.secret(), &nonced_state_hash) - .unwrap() - .into_electrum(), - ) - }) - .collect(); - let public_tx = pm - .public_transaction(private_state, &private_tx, &signatures, 1.into(), 0.into()) - .unwrap(); - let public_tx = public_tx.sign(&key1.secret(), chain_id); - push_block_with_transactions(&client, &[public_tx]); - - trace!("Querying private state"); - let mut query_tx = Transaction::default(); - query_tx.action = Action::Call(address.clone()); - query_tx.data = "0c55699c".from_hex().unwrap(); // getX - query_tx.gas = 50000.into(); - query_tx.nonce = 2.into(); - let query_tx = query_tx.sign(&key1.secret(), chain_id); - let result = pm.private_call(BlockId::Latest, &query_tx).unwrap(); - assert_eq!( - &result.output[..], - &("2a00000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap()[..]) - ); - assert_eq!( - pm.get_validators(BlockId::Latest, &address).unwrap(), - validators - ); - - // Now try modification with just one signature - trace!("Modifying private state"); - let mut private_tx = Transaction::default(); - private_tx.action = Action::Call(address.clone()); - private_tx.data = "bc64b76d2b00000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap(); //setX(43) - private_tx.gas = 120000.into(); - private_tx.nonce = 2.into(); - let private_tx = private_tx.sign(&key1.secret(), None); - let private_state = pm - .execute_private_transaction(BlockId::Latest, &private_tx) - .unwrap(); - let private_state_hash = keccak(&private_state); - let signatures: Vec<_> = [&key4] - .iter() - .map(|k| { - Signature::from( - ::ethkey::sign(&k.secret(), &private_state_hash) - .unwrap() - .into_electrum(), - ) - }) - .collect(); - let public_tx = pm - .public_transaction(private_state, &private_tx, &signatures, 2.into(), 0.into()) - .unwrap(); - let public_tx = public_tx.sign(&key1.secret(), chain_id); - push_block_with_transactions(&client, &[public_tx]); - - trace!("Querying private state"); - let mut query_tx = Transaction::default(); - query_tx.action = Action::Call(address.clone()); - query_tx.data = "0c55699c".from_hex().unwrap(); // getX - query_tx.gas = 50000.into(); - query_tx.nonce = 3.into(); - let query_tx = query_tx.sign(&key1.secret(), chain_id); - let result = pm.private_call(BlockId::Latest, &query_tx).unwrap(); - assert_eq!( - result.output, - "2a00000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap() - ); -} - -#[test] -fn call_other_private_contract() { - // This test verifies calls private contract methods from another one - // Two contract will be deployed - // The same contract A: - // contract Test1 { - // bytes32 public x; - // function setX(bytes32 _x) { - // x = _x; - // } - // } - // And the following contract B: - // contract Deployed { - // function setX(uint) {} - // function x() returns (uint) {} - //} - // contract Existing { - // Deployed dc; - // function Existing(address t) { - // dc = Deployed(t); - // } - // function getX() returns (uint) { - // return dc.x(); - // } - // } - //ethcore_logger::init_log(); - - // Create client and provider - let client = generate_dummy_client(0); - let chain_id = client.signing_chain_id(); - let key1 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000011", - )) - .unwrap(); - let _key2 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000012", - )) - .unwrap(); - let key3 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000013", - )) - .unwrap(); - let key4 = KeyPair::from_secret(Secret::from( - "0000000000000000000000000000000000000000000000000000000000000014", - )) - .unwrap(); - let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![ - key1.clone(), - key3.clone(), - key4.clone(), - ])); - - let config = ProviderConfig { - validator_accounts: vec![key3.address(), key4.address()], - signer_account: None, - }; - - let io = ethcore_io::IoChannel::disconnected(); - let miner = Arc::new(Miner::new_for_tests( - &::ethcore::spec::Spec::new_test(), - None, - )); - let private_keys = Arc::new(StoringKeyProvider::default()); - let pm = Arc::new(Provider::new( - client.clone(), - miner, - signer.clone(), - Box::new(NoopEncryptor::default()), - config, - io, - private_keys.clone(), - )); - - // Deploy contract A - let (address_a, _) = contract_address( - CreateContractAddress::FromSenderAndNonce, - &key1.address(), - &0.into(), - &[], - ); - trace!("Creating private contract A"); - let private_contract_a_test = "6060604052341561000f57600080fd5b60d88061001d6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c146046578063bc64b76d14607457600080fd5b3415605057600080fd5b60566098565b60405180826000191660001916815260200191505060405180910390f35b3415607e57600080fd5b6096600480803560001916906020019091905050609e565b005b60005481565b8060008160001916905550505600a165627a7a723058206acbdf4b15ca4c2d43e1b1879b830451a34f1e9d02ff1f2f394d8d857e79d2080029".from_hex().unwrap(); - let mut private_create_tx1 = Transaction::default(); - private_create_tx1.action = Action::Create; - private_create_tx1.data = private_contract_a_test; - private_create_tx1.gas = 200000.into(); - private_create_tx1.nonce = 0.into(); - let private_create_tx_signed = private_create_tx1.sign(&key1.secret(), None); - let validators = vec![key3.address(), key4.address()]; - let (public_tx1, _) = pm - .public_creation_transaction( - BlockId::Latest, - &private_create_tx_signed, - &validators, - 0.into(), - ) - .unwrap(); - let public_tx1 = public_tx1.sign(&key1.secret(), chain_id); - trace!("Transaction created. Pushing block"); - push_block_with_transactions(&client, &[public_tx1]); - - // Deploy contract B - let (address_b, _) = contract_address( - CreateContractAddress::FromSenderAndNonce, - &key1.address(), - &1.into(), - &[], - ); - trace!("Creating private contract B"); - // Build constructor data - let mut deploy_data = "6060604052341561000f57600080fd5b6040516020806101c583398101604052808051906020019091905050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061014a8061007b6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635197c7aa14610046575b600080fd5b341561005157600080fd5b61005961006f565b6040518082815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630c55699c6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156100fe57600080fd5b6102c65a03f1151561010f57600080fd5b505050604051805190509050905600a165627a7a723058207f8994e02725b47d76ec73e5c54a338d27b306dd1c830276bff2d75fcd1a5c920029000000000000000000000000".to_string(); - deploy_data.push_str(&address_a.to_vec().to_hex()); - let private_contract_b_test = deploy_data.from_hex().unwrap(); - let mut private_create_tx2 = Transaction::default(); - private_create_tx2.action = Action::Create; - private_create_tx2.data = private_contract_b_test; - private_create_tx2.gas = 200000.into(); - private_create_tx2.nonce = 1.into(); - let private_create_tx_signed = private_create_tx2.sign(&key1.secret(), None); - let (public_tx2, _) = pm - .public_creation_transaction( - BlockId::Latest, - &private_create_tx_signed, - &validators, - 0.into(), - ) - .unwrap(); - let public_tx2 = public_tx2.sign(&key1.secret(), chain_id); - trace!("Transaction created. Pushing block"); - push_block_with_transactions(&client, &[public_tx2]); - - // Let provider know, that it has access to both keys for A and B - private_keys.set_available_keys(&vec![address_a, address_b]); - - // Call A.setx(42) - trace!("Modifying private state"); - let mut private_tx = Transaction::default(); - private_tx.action = Action::Call(address_a.clone()); - private_tx.data = "bc64b76d2a00000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap(); //setX(42) - private_tx.gas = 120000.into(); - private_tx.nonce = 2.into(); - let private_tx = private_tx.sign(&key1.secret(), None); - let private_contract_nonce = pm.get_contract_nonce(&address_b, BlockId::Latest).unwrap(); - let private_state = pm - .execute_private_transaction(BlockId::Latest, &private_tx) - .unwrap(); - let nonced_state_hash = pm.calculate_state_hash(&private_state, private_contract_nonce); - let signatures: Vec<_> = [&key3, &key4] - .iter() - .map(|k| { - Signature::from( - ::ethkey::sign(&k.secret(), &nonced_state_hash) - .unwrap() - .into_electrum(), - ) - }) - .collect(); - let public_tx = pm - .public_transaction(private_state, &private_tx, &signatures, 2.into(), 0.into()) - .unwrap(); - let public_tx = public_tx.sign(&key1.secret(), chain_id); - push_block_with_transactions(&client, &[public_tx]); - - // Call B.getX() - trace!("Querying private state"); - let mut query_tx = Transaction::default(); - query_tx.action = Action::Call(address_b.clone()); - query_tx.data = "5197c7aa".from_hex().unwrap(); // getX - query_tx.gas = 50000.into(); - query_tx.nonce = 3.into(); - let query_tx = query_tx.sign(&key1.secret(), chain_id); - let result = pm.private_call(BlockId::Latest, &query_tx).unwrap(); - assert_eq!( - &result.output[..], - &("2a00000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap()[..]) - ); -} diff --git a/ethcore/service/Cargo.toml b/ethcore/service/Cargo.toml index c0be41038..68c73b4f9 100644 --- a/ethcore/service/Cargo.toml +++ b/ethcore/service/Cargo.toml @@ -10,7 +10,6 @@ error-chain = { version = "0.12", default-features = false } ethcore = { path = ".." } ethcore-blockchain = { path = "../blockchain" } ethcore-io = { path = "../../util/io" } -ethcore-private-tx = { path = "../private-tx" } ethcore-sync = { path = "../sync" } ethereum-types = "0.4" kvdb = "0.1" diff --git a/ethcore/service/src/error.rs b/ethcore/service/src/error.rs index 0d03a02d4..4786d4ffb 100644 --- a/ethcore/service/src/error.rs +++ b/ethcore/service/src/error.rs @@ -19,13 +19,11 @@ #![allow(deprecated)] use ethcore; -use ethcore_private_tx; use io; error_chain! { foreign_links { Ethcore(ethcore::error::Error); IoError(io::IoError); - PrivateTransactions(ethcore_private_tx::Error); } } diff --git a/ethcore/service/src/lib.rs b/ethcore/service/src/lib.rs index 7828fff8b..56c88e5af 100644 --- a/ethcore/service/src/lib.rs +++ b/ethcore/service/src/lib.rs @@ -18,7 +18,6 @@ extern crate ansi_term; extern crate ethcore; extern crate ethcore_blockchain as blockchain; extern crate ethcore_io as io; -extern crate ethcore_private_tx; extern crate ethcore_sync as sync; extern crate ethereum_types; extern crate kvdb; @@ -43,4 +42,4 @@ mod stop_guard; extern crate kvdb_rocksdb; pub use error::{Error, ErrorKind}; -pub use service::{ClientService, PrivateTxService}; +pub use service::ClientService; diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 6efe3beaf..ed2d36f51 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -19,7 +19,6 @@ use std::{path::Path, sync::Arc, time::Duration}; use ansi_term::Colour; -use ethereum_types::H256; use io::{IoContext, IoError, IoHandler, IoService, TimerToken}; use stop_guard::StopGuard; @@ -34,54 +33,14 @@ use ethcore::{ }, spec::Spec, }; -use sync::PrivateTxHandler; -use ethcore_private_tx::{self, Importer, Signer}; use Error; -pub struct PrivateTxService { - provider: Arc, -} - -impl PrivateTxService { - fn new(provider: Arc) -> Self { - PrivateTxService { provider } - } - - /// Returns underlying provider. - pub fn provider(&self) -> Arc { - self.provider.clone() - } -} - -impl PrivateTxHandler for PrivateTxService { - fn import_private_transaction(&self, rlp: &[u8]) -> Result { - match self.provider.import_private_transaction(rlp) { - Ok(import_result) => Ok(import_result), - Err(err) => { - warn!(target: "privatetx", "Unable to import private transaction packet: {}", err); - bail!(err.to_string()) - } - } - } - - fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result { - match self.provider.import_signed_private_transaction(rlp) { - Ok(import_result) => Ok(import_result), - Err(err) => { - warn!(target: "privatetx", "Unable to import signed private transaction packet: {}", err); - bail!(err.to_string()) - } - } - } -} - /// Client service setup. Creates and registers client and network services with the IO subsystem. pub struct ClientService { io_service: Arc>, client: Arc, snapshot: Arc, - private_tx: Arc, database: Arc, _stop_guard: StopGuard, } @@ -96,10 +55,6 @@ impl ClientService { restoration_db_handler: Box, _ipc_path: &Path, miner: Arc, - signer: Arc, - encryptor: Box, - private_tx_conf: ethcore_private_tx::ProviderConfig, - private_encryptor_conf: ethcore_private_tx::EncryptorConfig, ) -> Result { let io_service = IoService::::start()?; @@ -131,21 +86,6 @@ impl ClientService { }; let snapshot = Arc::new(SnapshotService::new(snapshot_params)?); - let private_keys = Arc::new(ethcore_private_tx::SecretStoreKeys::new( - client.clone(), - private_encryptor_conf.key_server_account, - )); - let provider = Arc::new(ethcore_private_tx::Provider::new( - client.clone(), - miner, - signer, - encryptor, - private_tx_conf, - io_service.channel(), - private_keys, - )); - let private_tx = Arc::new(PrivateTxService::new(provider)); - let client_io = Arc::new(ClientIoHandler { client: client.clone(), snapshot: snapshot.clone(), @@ -160,7 +100,6 @@ impl ClientService { io_service: Arc::new(io_service), client: client, snapshot: snapshot, - private_tx, database: blockchain_db, _stop_guard: stop_guard, }) @@ -184,11 +123,6 @@ impl ClientService { self.snapshot.clone() } - /// Get private transaction service. - pub fn private_tx_service(&self) -> Arc { - self.private_tx.clone() - } - /// Get network service component pub fn io(&self) -> Arc> { self.io_service.clone() @@ -309,8 +243,6 @@ mod tests { use ethcore_db::NUM_COLUMNS; use kvdb_rocksdb::{CompactionProfile, DatabaseConfig}; - use ethcore_private_tx; - #[test] fn it_can_be_started() { let tempdir = TempDir::new("").unwrap(); @@ -336,10 +268,6 @@ mod tests { restoration_db_handler, tempdir.path(), Arc::new(Miner::new_for_tests(&spec, None)), - Arc::new(ethcore_private_tx::DummySigner), - Box::new(ethcore_private_tx::NoopEncryptor), - Default::default(), - Default::default(), ); assert!(service.is_ok()); drop(service.unwrap()); diff --git a/ethcore/src/client/chain_notify.rs b/ethcore/src/client/chain_notify.rs index 302ab8546..4977451f1 100644 --- a/ethcore/src/client/chain_notify.rs +++ b/ethcore/src/client/chain_notify.rs @@ -24,10 +24,6 @@ use types::transaction::UnverifiedTransaction; pub enum ChainMessageType { /// Consensus message Consensus(Vec), - /// Message with private transaction - PrivateTransaction(H256, Vec), - /// Message with signed private transaction - SignedPrivateTransaction(H256, Vec), } /// Route type to indicate whether it is enacted or retracted. diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 3c5337d6d..d20368f86 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -60,4 +60,3 @@ pub use verification::VerifierType; pub mod traits; mod chain_notify; -mod private_notify; diff --git a/ethcore/src/client/private_notify.rs b/ethcore/src/client/private_notify.rs deleted file mode 100644 index 2c264eb75..000000000 --- a/ethcore/src/client/private_notify.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -use error::TransactionImportError; - -/// Represent private transactions handler inside the client -pub trait PrivateNotify: Send + Sync { - /// fires when private transaction message queued via client io queue - fn private_transaction_queued(&self) -> Result<(), TransactionImportError>; -} diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 106f44c54..5a7eea744 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -614,8 +614,6 @@ impl ChainNotify for TestNotify { fn broadcast(&self, message: ChainMessageType) { let data = match message { ChainMessageType::Consensus(data) => data, - ChainMessageType::SignedPrivateTransaction(_, data) => data, - ChainMessageType::PrivateTransaction(_, data) => data, }; self.messages.write().push(data); } diff --git a/ethcore/sync/Cargo.toml b/ethcore/sync/Cargo.toml index 64ae9b141..09d5fa042 100644 --- a/ethcore/sync/Cargo.toml +++ b/ethcore/sync/Cargo.toml @@ -36,6 +36,5 @@ triehash-ethereum = {version = "0.2", path = "../../util/triehash-ethereum" } env_logger = "0.5" ethcore = { path = "..", features = ["test-helpers"] } ethcore-io = { path = "../../util/io", features = ["mio"] } -ethcore-private-tx = { path = "../private-tx" } kvdb-memorydb = "0.1" rustc-hex = "1.0" diff --git a/ethcore/sync/src/api.rs b/ethcore/sync/src/api.rs index fe15acae2..0b6000b96 100644 --- a/ethcore/sync/src/api.rs +++ b/ethcore/sync/src/api.rs @@ -30,9 +30,8 @@ use std::{ }; use chain::{ - sync_packet::SyncPacket::{PrivateTransactionPacket, SignedPrivateTransactionPacket}, ChainSyncApi, SyncStatus as EthSyncStatus, ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63, - PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, PAR_PROTOCOL_VERSION_3, + PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, }; use ethcore::{ client::{BlockChainClient, ChainMessageType, ChainNotify, NewBlocks}, @@ -43,7 +42,6 @@ use ethkey::Secret; use io::TimerToken; use network::IpFilter; use parking_lot::{Mutex, RwLock}; -use private_tx::PrivateTxHandler; use std::{ net::{AddrParseError, SocketAddr}, str::FromStr, @@ -214,8 +212,6 @@ pub struct Params { pub chain: Arc, /// Snapshot service. pub snapshot_service: Arc, - /// Private tx service. - pub private_tx_handler: Option>, /// Network layer configuration. pub network_config: NetworkConfiguration, } @@ -239,12 +235,7 @@ impl EthSync { connection_filter: Option>, ) -> Result, Error> { let (priority_tasks_tx, priority_tasks_rx) = mpsc::channel(); - let sync = ChainSyncApi::new( - params.config, - &*params.chain, - params.private_tx_handler.as_ref().cloned(), - priority_tasks_rx, - ); + let sync = ChainSyncApi::new(params.config, &*params.chain, priority_tasks_rx); let service = NetworkService::new( params.network_config.clone().into_basic()?, connection_filter, @@ -463,11 +454,7 @@ impl ChainNotify for EthSync { .register_protocol( self.eth_handler.clone(), PAR_PROTOCOL, - &[ - PAR_PROTOCOL_VERSION_1, - PAR_PROTOCOL_VERSION_2, - PAR_PROTOCOL_VERSION_3, - ], + &[PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2], ) .unwrap_or_else(|e| warn!("Error registering snapshot sync protocol: {:?}", e)); } @@ -491,22 +478,6 @@ impl ChainNotify for EthSync { .sync .write() .propagate_consensus_packet(&mut sync_io, message), - ChainMessageType::PrivateTransaction(transaction_hash, message) => { - self.eth_handler.sync.write().propagate_private_transaction( - &mut sync_io, - transaction_hash, - PrivateTransactionPacket, - message, - ) - } - ChainMessageType::SignedPrivateTransaction(transaction_hash, message) => { - self.eth_handler.sync.write().propagate_private_transaction( - &mut sync_io, - transaction_hash, - SignedPrivateTransactionPacket, - message, - ) - } } }); } diff --git a/ethcore/sync/src/chain/handler.rs b/ethcore/sync/src/chain/handler.rs index a7c4aa6f1..6cbdedac1 100644 --- a/ethcore/sync/src/chain/handler.rs +++ b/ethcore/sync/src/chain/handler.rs @@ -36,15 +36,14 @@ use super::sync_packet::{ PacketInfo, SyncPacket, SyncPacket::{ BlockBodiesPacket, BlockHeadersPacket, NewBlockHashesPacket, NewBlockPacket, - PrivateTransactionPacket, ReceiptsPacket, SignedPrivateTransactionPacket, - SnapshotDataPacket, SnapshotManifestPacket, StatusPacket, + ReceiptsPacket, SnapshotDataPacket, SnapshotManifestPacket, StatusPacket, }, }; use super::{ BlockSet, ChainSync, ForkConfirmation, PacketDecodeError, PeerAsking, PeerInfo, SyncRequester, SyncState, ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63, MAX_NEW_BLOCK_AGE, MAX_NEW_HASHES, - PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_3, + PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2, }; /// The Chain Sync Handler: handles responses from peers @@ -70,12 +69,6 @@ impl SyncHandler { NewBlockHashesPacket => SyncHandler::on_peer_new_hashes(sync, io, peer, &rlp), SnapshotManifestPacket => SyncHandler::on_snapshot_manifest(sync, io, peer, &rlp), SnapshotDataPacket => SyncHandler::on_snapshot_data(sync, io, peer, &rlp), - PrivateTransactionPacket => { - SyncHandler::on_private_transaction(sync, io, peer, &rlp) - } - SignedPrivateTransactionPacket => { - SyncHandler::on_signed_private_transaction(sync, io, peer, &rlp) - } _ => { debug!(target: "sync", "{}: Unknown packet {}", peer, packet_id.id()); Ok(()) @@ -661,7 +654,6 @@ impl SyncHandler { let protocol_version: u8 = r.val_at(0)?; let warp_protocol_version = io.protocol_version(&PAR_PROTOCOL, peer_id); let warp_protocol = warp_protocol_version != 0; - let private_tx_protocol = warp_protocol_version >= PAR_PROTOCOL_VERSION_3.0; let peer = PeerInfo { protocol_version: protocol_version, network_id: r.val_at(1)?, @@ -673,7 +665,6 @@ impl SyncHandler { asking_hash: None, ask_time: Instant::now(), last_sent_transactions: Default::default(), - last_sent_private_transactions: Default::default(), expired: false, confirmation: if sync.fork_block.is_none() { ForkConfirmation::Confirmed @@ -692,11 +683,6 @@ impl SyncHandler { None }, block_set: None, - private_tx_enabled: if private_tx_protocol { - r.val_at(7).unwrap_or(false) - } else { - false - }, client_version: ClientVersion::from(io.peer_version(peer_id)), }; @@ -706,16 +692,14 @@ impl SyncHandler { difficulty: {:?}, \ latest:{}, \ genesis:{}, \ - snapshot:{:?}, \ - private_tx_enabled:{})", + snapshot:{:?})", peer_id, peer.protocol_version, peer.network_id, peer.difficulty, peer.latest_hash, peer.genesis, - peer.snapshot_number, - peer.private_tx_enabled + peer.snapshot_number ); if io.is_expired() { trace!(target: "sync", "Status packet from expired session {}:{}", peer_id, io.peer_version(peer_id)); @@ -739,7 +723,7 @@ impl SyncHandler { if false || (warp_protocol && (peer.protocol_version < PAR_PROTOCOL_VERSION_1.0 - || peer.protocol_version > PAR_PROTOCOL_VERSION_3.0)) + || peer.protocol_version > PAR_PROTOCOL_VERSION_2.0)) || (!warp_protocol && (peer.protocol_version < ETH_PROTOCOL_VERSION_62.0 || peer.protocol_version > ETH_PROTOCOL_VERSION_63.0)) @@ -795,72 +779,6 @@ impl SyncHandler { io.chain().queue_transactions(transactions, peer_id); Ok(()) } - - /// Called when peer sends us signed private transaction packet - fn on_signed_private_transaction( - sync: &mut ChainSync, - _io: &mut dyn SyncIo, - peer_id: PeerId, - r: &Rlp, - ) -> Result<(), DownloaderImportError> { - if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); - return Ok(()); - } - let private_handler = match sync.private_tx_handler { - Some(ref handler) => handler, - None => { - trace!(target: "sync", "{} Ignoring private tx packet from peer", peer_id); - return Ok(()); - } - }; - trace!(target: "sync", "Received signed private transaction packet from {:?}", peer_id); - match private_handler.import_signed_private_transaction(r.as_raw()) { - Ok(transaction_hash) => { - //don't send the packet back - if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { - peer.last_sent_private_transactions.insert(transaction_hash); - } - } - Err(e) => { - trace!(target: "sync", "Ignoring the message, error queueing: {}", e); - } - } - Ok(()) - } - - /// Called when peer sends us new private transaction packet - fn on_private_transaction( - sync: &mut ChainSync, - _io: &mut dyn SyncIo, - peer_id: PeerId, - r: &Rlp, - ) -> Result<(), DownloaderImportError> { - if !sync.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { - trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); - return Ok(()); - } - let private_handler = match sync.private_tx_handler { - Some(ref handler) => handler, - None => { - trace!(target: "sync", "{} Ignoring private tx packet from peer", peer_id); - return Ok(()); - } - }; - trace!(target: "sync", "Received private transaction packet from {:?}", peer_id); - match private_handler.import_private_transaction(r.as_raw()) { - Ok(transaction_hash) => { - //don't send the packet back - if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { - peer.last_sent_private_transactions.insert(transaction_hash); - } - } - Err(e) => { - trace!(target: "sync", "Ignoring the message, error queueing: {}", e); - } - } - Ok(()) - } } #[cfg(test)] diff --git a/ethcore/sync/src/chain/mod.rs b/ethcore/sync/src/chain/mod.rs index 74fe324de..ccea28817 100644 --- a/ethcore/sync/src/chain/mod.rs +++ b/ethcore/sync/src/chain/mod.rs @@ -107,14 +107,13 @@ use hash::keccak; use heapsize::HeapSizeOf; use network::{self, client_version::ClientVersion, PacketId, PeerId}; use parking_lot::{Mutex, RwLock, RwLockWriteGuard}; -use private_tx::PrivateTxHandler; use rand::Rng; use rlp::{DecoderError, RlpStream}; use snapshot::Snapshot; use std::{ cmp, collections::{BTreeMap, HashMap, HashSet}, - sync::{mpsc, Arc}, + sync::mpsc, time::{Duration, Instant}, }; use sync_io::SyncIo; @@ -124,7 +123,7 @@ use types::{transaction::UnverifiedTransaction, BlockNumber}; use self::{ handler::SyncHandler, sync_packet::{ - PacketInfo, SyncPacket, + PacketInfo, SyncPacket::{NewBlockPacket, StatusPacket}, }, }; @@ -144,8 +143,6 @@ pub const ETH_PROTOCOL_VERSION_62: (u8, u8) = (62, 0x11); pub const PAR_PROTOCOL_VERSION_1: (u8, u8) = (1, 0x15); /// 2 version of Parity protocol (consensus messages added). pub const PAR_PROTOCOL_VERSION_2: (u8, u8) = (2, 0x16); -/// 3 version of Parity protocol (private transactions messages added). -pub const PAR_PROTOCOL_VERSION_3: (u8, u8) = (3, 0x18); pub const MAX_BODIES_TO_SEND: usize = 256; pub const MAX_HEADERS_TO_SEND: usize = 512; @@ -318,12 +315,8 @@ pub struct PeerInfo { ask_time: Instant, /// Holds a set of transactions recently sent to this peer to avoid spamming. last_sent_transactions: H256FastSet, - /// Holds a set of private transactions and their signatures recently sent to this peer to avoid spamming. - last_sent_private_transactions: H256FastSet, /// Pending request is expired and result should be ignored expired: bool, - /// Private transactions enabled - private_tx_enabled: bool, /// Peer fork confirmation status confirmation: ForkConfirmation, /// Best snapshot hash @@ -353,10 +346,6 @@ impl PeerInfo { self.expired = true; } } - - fn reset_private_stats(&mut self) { - self.last_sent_private_transactions.clear(); - } } #[cfg(not(test))] @@ -392,11 +381,10 @@ impl ChainSyncApi { pub fn new( config: SyncConfig, chain: &dyn BlockChainClient, - private_tx_handler: Option>, priority_tasks: mpsc::Receiver, ) -> Self { ChainSyncApi { - sync: RwLock::new(ChainSync::new(config, chain, private_tx_handler)), + sync: RwLock::new(ChainSync::new(config, chain)), priority_tasks: Mutex::new(priority_tasks), } } @@ -640,19 +628,13 @@ pub struct ChainSync { transactions_stats: TransactionsStats, /// Enable ancient block downloading download_old_blocks: bool, - /// Shared private tx service. - private_tx_handler: Option>, /// Enable warp sync. warp_sync: WarpSync, } impl ChainSync { /// Create a new instance of syncing strategy. - pub fn new( - config: SyncConfig, - chain: &dyn BlockChainClient, - private_tx_handler: Option>, - ) -> Self { + pub fn new(config: SyncConfig, chain: &dyn BlockChainClient) -> Self { let chain_info = chain.chain_info(); let best_block = chain.chain_info().best_block_number; let state = Self::get_init_state(config.warp_sync, chain); @@ -677,7 +659,6 @@ impl ChainSync { snapshot: Snapshot::new(), sync_start_time: None, transactions_stats: TransactionsStats::default(), - private_tx_handler, warp_sync: config.warp_sync, }; sync.update_targets(chain); @@ -1207,7 +1188,6 @@ impl ChainSync { fn send_status(&mut self, io: &mut dyn SyncIo, peer: PeerId) -> Result<(), network::Error> { let warp_protocol_version = io.protocol_version(&PAR_PROTOCOL, peer); let warp_protocol = warp_protocol_version != 0; - let private_tx_protocol = warp_protocol_version >= PAR_PROTOCOL_VERSION_3.0; let protocol = if warp_protocol { warp_protocol_version } else { @@ -1228,9 +1208,6 @@ impl ChainSync { let manifest_hash = manifest.map_or(H256::new(), |m| keccak(m.into_rlp())); packet.append(&manifest_hash); packet.append(&block_number); - if private_tx_protocol { - packet.append(&self.private_tx_handler.is_some()); - } } packet.complete_unbounded_list(); io.respond(StatusPacket.id(), packet.out()) @@ -1355,22 +1332,6 @@ impl ChainSync { .collect() } - fn get_private_transaction_peers(&self, transaction_hash: &H256) -> Vec { - self.peers - .iter() - .filter_map(|(id, p)| { - if p.protocol_version >= PAR_PROTOCOL_VERSION_3.0 - && !p.last_sent_private_transactions.contains(transaction_hash) - && p.private_tx_enabled - { - Some(*id) - } else { - None - } - }) - .collect() - } - /// Maintain other peers. Send out any new blocks and transactions pub fn maintain_sync(&mut self, io: &mut dyn SyncIo) { self.maybe_start_snapshot_sync(io); @@ -1407,7 +1368,6 @@ impl ChainSync { trace!(target: "sync", "Re-broadcasting transactions to a random peer."); self.peers.values_mut().nth(peer).map(|peer_info| { peer_info.last_sent_transactions.clear(); - peer_info.reset_private_stats() }); } } @@ -1443,23 +1403,6 @@ impl ChainSync { pub fn propagate_consensus_packet(&mut self, io: &mut dyn SyncIo, packet: Bytes) { SyncPropagator::propagate_consensus_packet(self, io, packet); } - - /// Broadcast private transaction message to peers. - pub fn propagate_private_transaction( - &mut self, - io: &mut dyn SyncIo, - transaction_hash: H256, - packet_id: SyncPacket, - packet: Bytes, - ) { - SyncPropagator::propagate_private_transaction( - self, - io, - transaction_hash, - packet_id, - packet, - ); - } } #[cfg(test)] @@ -1565,7 +1508,7 @@ pub mod tests { peer_latest_hash: H256, client: &dyn BlockChainClient, ) -> ChainSync { - let mut sync = ChainSync::new(SyncConfig::default(), client, None); + let mut sync = ChainSync::new(SyncConfig::default(), client); insert_dummy_peer(&mut sync, 0, peer_latest_hash); sync } @@ -1584,9 +1527,7 @@ pub mod tests { asking_hash: None, ask_time: Instant::now(), last_sent_transactions: Default::default(), - last_sent_private_transactions: Default::default(), expired: false, - private_tx_enabled: false, confirmation: super::ForkConfirmation::Confirmed, snapshot_number: None, snapshot_hash: None, diff --git a/ethcore/sync/src/chain/propagator.rs b/ethcore/sync/src/chain/propagator.rs index c0d92d950..67e711e1d 100644 --- a/ethcore/sync/src/chain/propagator.rs +++ b/ethcore/sync/src/chain/propagator.rs @@ -328,29 +328,6 @@ impl SyncPropagator { } } - /// Broadcast private transaction message to peers. - pub fn propagate_private_transaction( - sync: &mut ChainSync, - io: &mut dyn SyncIo, - transaction_hash: H256, - packet_id: SyncPacket, - packet: Bytes, - ) { - let lucky_peers = - ChainSync::select_random_peers(&sync.get_private_transaction_peers(&transaction_hash)); - if lucky_peers.is_empty() { - error!(target: "privatetx", "Cannot propagate the packet, no peers with private tx enabled connected"); - } else { - trace!(target: "privatetx", "Sending private transaction packet to {:?}", lucky_peers); - for peer_id in lucky_peers { - if let Some(ref mut peer) = sync.peers.get_mut(&peer_id) { - peer.last_sent_private_transactions.insert(transaction_hash); - } - SyncPropagator::send_packet(io, peer_id, packet_id, packet.clone()); - } - } - } - fn select_peers_for_transactions(sync: &ChainSync, filter: F) -> Vec where F: Fn(&PeerId) -> bool, @@ -473,7 +450,7 @@ mod tests { client.add_blocks(2, EachBlockWith::Uncle); let queue = RwLock::new(VecDeque::new()); let block = client.block(BlockId::Latest).unwrap().into_inner(); - let mut sync = ChainSync::new(SyncConfig::default(), &client, None); + let mut sync = ChainSync::new(SyncConfig::default(), &client); sync.peers.insert( 0, PeerInfo { @@ -488,9 +465,7 @@ mod tests { asking_hash: None, ask_time: Instant::now(), last_sent_transactions: Default::default(), - last_sent_private_transactions: Default::default(), expired: false, - private_tx_enabled: false, confirmation: ForkConfirmation::Confirmed, snapshot_number: None, snapshot_hash: None, @@ -565,7 +540,7 @@ mod tests { client.add_blocks(100, EachBlockWith::Uncle); client.insert_transaction_to_queue(); // Sync with no peers - let mut sync = ChainSync::new(SyncConfig::default(), &client, None); + let mut sync = ChainSync::new(SyncConfig::default(), &client); let queue = RwLock::new(VecDeque::new()); let ss = TestSnapshotService::new(); let mut io = TestIo::new(&mut client, &ss, &queue, None); @@ -642,7 +617,7 @@ mod tests { let mut client = TestBlockChainClient::new(); client.insert_transaction_with_gas_price_to_queue(U256::zero()); let block_hash = client.block_hash_delta_minus(1); - let mut sync = ChainSync::new(SyncConfig::default(), &client, None); + let mut sync = ChainSync::new(SyncConfig::default(), &client); let queue = RwLock::new(VecDeque::new()); let ss = TestSnapshotService::new(); let mut io = TestIo::new(&mut client, &ss, &queue, None); @@ -680,7 +655,7 @@ mod tests { let tx1_hash = client.insert_transaction_to_queue(); let tx2_hash = client.insert_transaction_with_gas_price_to_queue(U256::zero()); let block_hash = client.block_hash_delta_minus(1); - let mut sync = ChainSync::new(SyncConfig::default(), &client, None); + let mut sync = ChainSync::new(SyncConfig::default(), &client); let queue = RwLock::new(VecDeque::new()); let ss = TestSnapshotService::new(); let mut io = TestIo::new(&mut client, &ss, &queue, None); diff --git a/ethcore/sync/src/chain/sync_packet.rs b/ethcore/sync/src/chain/sync_packet.rs index 221c7a330..3567c7476 100644 --- a/ethcore/sync/src/chain/sync_packet.rs +++ b/ethcore/sync/src/chain/sync_packet.rs @@ -55,8 +55,6 @@ pub enum SyncPacket { GetSnapshotDataPacket = 0x13, SnapshotDataPacket = 0x14, ConsensusDataPacket = 0x15, - PrivateTransactionPacket = 0x16, - SignedPrivateTransactionPacket = 0x17, } } @@ -91,9 +89,7 @@ impl PacketInfo for SyncPacket { | SnapshotManifestPacket | GetSnapshotDataPacket | SnapshotDataPacket - | ConsensusDataPacket - | PrivateTransactionPacket - | SignedPrivateTransactionPacket => PAR_PROTOCOL, + | ConsensusDataPacket => PAR_PROTOCOL, } } diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index 97541adf1..4440a4b27 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -40,8 +40,6 @@ extern crate triehash_ethereum; #[cfg(test)] extern crate env_logger; #[cfg(test)] -extern crate ethcore_private_tx; -#[cfg(test)] extern crate kvdb_memorydb; #[cfg(test)] extern crate rustc_hex; @@ -60,7 +58,6 @@ extern crate trace_time; mod block_sync; mod blocks; mod chain; -mod private_tx; mod snapshot; mod sync_io; mod transactions_stats; @@ -74,4 +71,3 @@ pub use api::*; pub use chain::{SyncState, SyncStatus}; pub use devp2p::validate_node_url; pub use network::{ConnectionDirection, ConnectionFilter, Error, ErrorKind, NonReservedPeerMode}; -pub use private_tx::{NoopPrivateTxHandler, PrivateTxHandler, SimplePrivateTxHandler}; diff --git a/ethcore/sync/src/private_tx.rs b/ethcore/sync/src/private_tx.rs deleted file mode 100644 index d086ef738..000000000 --- a/ethcore/sync/src/private_tx.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -use ethereum_types::H256; -use parking_lot::Mutex; - -/// Trait which should be implemented by a private transaction handler. -pub trait PrivateTxHandler: Send + Sync + 'static { - /// Function called on new private transaction received. - /// Returns the hash of the imported transaction - fn import_private_transaction(&self, rlp: &[u8]) -> Result; - - /// Function called on new signed private transaction received. - /// Returns the hash of the imported transaction - fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result; -} - -/// Nonoperative private transaction handler. -pub struct NoopPrivateTxHandler; - -impl PrivateTxHandler for NoopPrivateTxHandler { - fn import_private_transaction(&self, _rlp: &[u8]) -> Result { - Ok(H256::default()) - } - - fn import_signed_private_transaction(&self, _rlp: &[u8]) -> Result { - Ok(H256::default()) - } -} - -/// Simple private transaction handler. Used for tests. -#[derive(Default)] -pub struct SimplePrivateTxHandler { - /// imported private transactions - pub txs: Mutex>>, - /// imported signed private transactions - pub signed_txs: Mutex>>, -} - -impl PrivateTxHandler for SimplePrivateTxHandler { - fn import_private_transaction(&self, rlp: &[u8]) -> Result { - self.txs.lock().push(rlp.to_vec()); - Ok(H256::default()) - } - - fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result { - self.signed_txs.lock().push(rlp.to_vec()); - Ok(H256::default()) - } -} diff --git a/ethcore/sync/src/tests/helpers.rs b/ethcore/sync/src/tests/helpers.rs index 04bdce4fc..71edae1ba 100644 --- a/ethcore/sync/src/tests/helpers.rs +++ b/ethcore/sync/src/tests/helpers.rs @@ -17,11 +17,8 @@ use api::PAR_PROTOCOL; use bytes::Bytes; use chain::{ - sync_packet::{ - PacketInfo, SyncPacket, - SyncPacket::{PrivateTransactionPacket, SignedPrivateTransactionPacket}, - }, - ChainSync, SyncSupplier, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_3, + sync_packet::{PacketInfo, SyncPacket}, + ChainSync, SyncSupplier, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_2, }; use ethcore::{ client::{ @@ -36,7 +33,7 @@ use ethcore::{ use ethereum_types::H256; use io::{IoChannel, IoContext, IoHandler}; use network::{self, client_version::ClientVersion, PacketId, PeerId, ProtocolId, SessionInfo}; -use parking_lot::{Mutex, RwLock}; +use parking_lot::RwLock; use std::{ collections::{HashMap, HashSet, VecDeque}, sync::Arc, @@ -44,7 +41,6 @@ use std::{ use sync_io::SyncIo; use tests::snapshot::*; -use private_tx::SimplePrivateTxHandler; use types::BlockNumber; use SyncConfig; @@ -177,7 +173,7 @@ where fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8 { if protocol == &PAR_PROTOCOL { - PAR_PROTOCOL_VERSION_3.0 + PAR_PROTOCOL_VERSION_2.0 } else { self.eth_protocol_version(peer_id) } @@ -262,7 +258,6 @@ where pub snapshot_service: Arc, pub sync: RwLock, pub queue: RwLock>, - pub private_tx_handler: Arc, pub io_queue: RwLock>, new_blocks_queue: RwLock>, } @@ -285,22 +280,6 @@ where ChainMessageType::Consensus(data) => { self.sync.write().propagate_consensus_packet(&mut io, data) } - ChainMessageType::PrivateTransaction(transaction_hash, data) => { - self.sync.write().propagate_private_transaction( - &mut io, - transaction_hash, - PrivateTransactionPacket, - data, - ) - } - ChainMessageType::SignedPrivateTransaction(transaction_hash, data) => { - self.sync.write().propagate_private_transaction( - &mut io, - transaction_hash, - SignedPrivateTransactionPacket, - data, - ) - } } } @@ -426,15 +405,13 @@ impl TestNet> { for _ in 0..n { let chain = TestBlockChainClient::new(); let ss = Arc::new(TestSnapshotService::new()); - let private_tx_handler = Arc::new(SimplePrivateTxHandler::default()); - let sync = ChainSync::new(config.clone(), &chain, Some(private_tx_handler.clone())); + let sync = ChainSync::new(config.clone(), &chain); net.peers.push(Arc::new(EthPeer { sync: RwLock::new(sync), snapshot_service: ss, chain: Arc::new(chain), miner: Arc::new(Miner::new_for_tests(&Spec::new_test(), None)), queue: RwLock::new(VecDeque::new()), - private_tx_handler, io_queue: RwLock::new(VecDeque::new()), new_blocks_queue: RwLock::new(VecDeque::new()), })); @@ -476,16 +453,14 @@ impl TestNet> { ) .unwrap(); - let private_tx_handler = Arc::new(SimplePrivateTxHandler::default()); let ss = Arc::new(TestSnapshotService::new()); - let sync = ChainSync::new(config, &*client, Some(private_tx_handler.clone())); + let sync = ChainSync::new(config, &*client); let peer = Arc::new(EthPeer { sync: RwLock::new(sync), snapshot_service: ss, chain: client, miner, queue: RwLock::new(VecDeque::new()), - private_tx_handler, io_queue: RwLock::new(VecDeque::new()), new_blocks_queue: RwLock::new(VecDeque::new()), }); @@ -604,15 +579,11 @@ impl TestNet> { pub struct TestIoHandler { pub client: Arc, - pub private_tx_queued: Mutex, } impl TestIoHandler { pub fn new(client: Arc) -> Self { - TestIoHandler { - client, - private_tx_queued: Mutex::default(), - } + TestIoHandler { client } } } @@ -620,7 +591,6 @@ impl IoHandler for TestIoHandler { fn message(&self, _io: &IoContext, net_message: &ClientIoMessage) { match *net_message { ClientIoMessage::Execute(ref exec) => { - *self.private_tx_queued.lock() += 1; (*exec.0)(&self.client); } _ => {} // ignore other messages diff --git a/ethcore/sync/src/tests/mod.rs b/ethcore/sync/src/tests/mod.rs index 16370ce3e..018eba008 100644 --- a/ethcore/sync/src/tests/mod.rs +++ b/ethcore/sync/src/tests/mod.rs @@ -17,7 +17,6 @@ mod chain; mod consensus; pub mod helpers; -mod private; pub mod snapshot; #[cfg(feature = "ipc")] diff --git a/ethcore/sync/src/tests/private.rs b/ethcore/sync/src/tests/private.rs deleted file mode 100644 index 29d5d959b..000000000 --- a/ethcore/sync/src/tests/private.rs +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -use ethcore::{ - client::{BlockChainClient, ClientIoMessage}, - engines, - executive::contract_address, - miner::{self, MinerService}, - spec::Spec, - test_helpers::push_block_with_transactions, - CreateContractAddress, -}; -use ethcore_private_tx::{ - Importer, NoopEncryptor, Provider, ProviderConfig, SignedPrivateTransaction, StoringKeyProvider, -}; -use ethkey::KeyPair; -use hash::keccak; -use io::{IoChannel, IoHandler}; -use rlp::Rlp; -use rustc_hex::FromHex; -use std::sync::Arc; -use tests::helpers::{TestIoHandler, TestNet}; -use types::{ - ids::BlockId, - transaction::{Action, Transaction}, -}; -use SyncConfig; - -fn seal_spec() -> Spec { - let spec_data = include_str!("../res/private_spec.json"); - Spec::load(&::std::env::temp_dir(), spec_data.as_bytes()).unwrap() -} - -#[test] -fn send_private_transaction() { - // Setup two clients - let s0 = KeyPair::from_secret_slice(&keccak("1")).unwrap(); - let s1 = KeyPair::from_secret_slice(&keccak("0")).unwrap(); - - let signer = Arc::new(ethcore_private_tx::KeyPairSigner(vec![ - s0.clone(), - s1.clone(), - ])); - - let mut net = TestNet::with_spec(2, SyncConfig::default(), seal_spec); - let client0 = net.peer(0).chain.clone(); - let client1 = net.peer(1).chain.clone(); - let io_handler0: Arc> = - Arc::new(TestIoHandler::new(net.peer(0).chain.clone())); - let io_handler1: Arc> = - Arc::new(TestIoHandler::new(net.peer(1).chain.clone())); - - net.peer(0) - .miner - .set_author(miner::Author::Sealer(engines::signer::from_keypair( - s0.clone(), - ))); - net.peer(1) - .miner - .set_author(miner::Author::Sealer(engines::signer::from_keypair( - s1.clone(), - ))); - net.peer(0) - .chain - .engine() - .register_client(Arc::downgrade(&net.peer(0).chain) as _); - net.peer(1) - .chain - .engine() - .register_client(Arc::downgrade(&net.peer(1).chain) as _); - net.peer(0) - .chain - .set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler0))); - net.peer(1) - .chain - .set_io_channel(IoChannel::to_handler(Arc::downgrade(&io_handler1))); - - let (address, _) = contract_address( - CreateContractAddress::FromSenderAndNonce, - &s0.address(), - &0.into(), - &[], - ); - let chain_id = client0.signing_chain_id(); - - // Exhange statuses - net.sync(); - - // Setup private providers - let validator_config = ProviderConfig { - validator_accounts: vec![s1.address()], - signer_account: None, - }; - - let signer_config = ProviderConfig { - validator_accounts: Vec::new(), - signer_account: Some(s0.address()), - }; - - let private_keys = Arc::new(StoringKeyProvider::default()); - - let pm0 = Arc::new(Provider::new( - client0.clone(), - net.peer(0).miner.clone(), - signer.clone(), - Box::new(NoopEncryptor::default()), - signer_config, - IoChannel::to_handler(Arc::downgrade(&io_handler0)), - private_keys.clone(), - )); - pm0.add_notify(net.peers[0].clone()); - - let pm1 = Arc::new(Provider::new( - client1.clone(), - net.peer(1).miner.clone(), - signer.clone(), - Box::new(NoopEncryptor::default()), - validator_config, - IoChannel::to_handler(Arc::downgrade(&io_handler1)), - private_keys.clone(), - )); - pm1.add_notify(net.peers[1].clone()); - - // Create and deploy contract - let private_contract_test = "6060604052341561000f57600080fd5b60d88061001d6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c55699c146046578063bc64b76d14607457600080fd5b3415605057600080fd5b60566098565b60405180826000191660001916815260200191505060405180910390f35b3415607e57600080fd5b6096600480803560001916906020019091905050609e565b005b60005481565b8060008160001916905550505600a165627a7a723058206acbdf4b15ca4c2d43e1b1879b830451a34f1e9d02ff1f2f394d8d857e79d2080029".from_hex().unwrap(); - let mut private_create_tx = Transaction::default(); - private_create_tx.action = Action::Create; - private_create_tx.data = private_contract_test; - private_create_tx.gas = 200000.into(); - let private_create_tx_signed = private_create_tx.sign(&s0.secret(), None); - let validators = vec![s1.address()]; - let (public_tx, _) = pm0 - .public_creation_transaction( - BlockId::Latest, - &private_create_tx_signed, - &validators, - 0.into(), - ) - .unwrap(); - let public_tx = public_tx.sign(&s0.secret(), chain_id); - - let public_tx_copy = public_tx.clone(); - push_block_with_transactions(&client0, &[public_tx]); - push_block_with_transactions(&client1, &[public_tx_copy]); - - net.sync(); - - //Create private transaction for modifying state - let mut private_tx = Transaction::default(); - private_tx.action = Action::Call(address.clone()); - private_tx.data = "bc64b76d2a00000000000000000000000000000000000000000000000000000000000000" - .from_hex() - .unwrap(); //setX(42) - private_tx.gas = 120000.into(); - private_tx.nonce = 1.into(); - let private_tx = private_tx.sign(&s0.secret(), None); - assert!(pm0.create_private_transaction(private_tx).is_ok()); - - //send private transaction message to validator - net.sync(); - - let validator_handler = net.peer(1).private_tx_handler.clone(); - let received_private_transactions = validator_handler.txs.lock().clone(); - assert_eq!(received_private_transactions.len(), 1); - - //process received private transaction message - let private_transaction = received_private_transactions[0].clone(); - assert!(pm1.import_private_transaction(&private_transaction).is_ok()); - - //send signed response - net.sync(); - - let sender_handler = net.peer(0).private_tx_handler.clone(); - let received_signed_private_transactions = sender_handler.signed_txs.lock().clone(); - assert_eq!(received_signed_private_transactions.len(), 1); - - //process signed response - let signed_private_transaction = received_signed_private_transactions[0].clone(); - assert!(pm0 - .import_signed_private_transaction(&signed_private_transaction) - .is_ok()); - let signature: SignedPrivateTransaction = - Rlp::new(&signed_private_transaction).as_val().unwrap(); - assert!(pm0.process_signature(&signature).is_ok()); - let local_transactions = net.peer(0).miner.local_transactions(); - assert_eq!(local_transactions.len(), 1); -} diff --git a/parity/account_utils.rs b/parity/account_utils.rs index f1c25e13f..391d00c1f 100644 --- a/parity/account_utils.rs +++ b/parity/account_utils.rs @@ -60,13 +60,6 @@ mod accounts { Ok(None) } - pub fn private_tx_signer( - _account_provider: Arc, - _passwords: &[Password], - ) -> Result, String> { - Ok(Arc::new(::ethcore_private_tx::DummySigner)) - } - pub fn accounts_list( _account_provider: Arc, ) -> Arc Vec
+ Send + Sync> { @@ -218,62 +211,6 @@ mod accounts { Ok(author) } - mod private_tx { - use super::*; - use ethcore_private_tx::Error; - use ethkey::{Message, Signature}; - - pub struct AccountSigner { - pub accounts: Arc, - pub passwords: Vec, - } - - impl ::ethcore_private_tx::Signer for AccountSigner { - fn decrypt( - &self, - account: Address, - shared_mac: &[u8], - payload: &[u8], - ) -> Result, Error> { - let password = self.find_account_password(&account); - Ok(self - .accounts - .decrypt(account, password, shared_mac, payload) - .map_err(|e| e.to_string())?) - } - - fn sign(&self, account: Address, hash: Message) -> Result { - let password = self.find_account_password(&account); - Ok(self - .accounts - .sign(account, password, hash) - .map_err(|e| e.to_string())?) - } - } - - impl AccountSigner { - /// Try to unlock account using stored password, return found password if any - fn find_account_password(&self, account: &Address) -> Option { - for password in &self.passwords { - if let Ok(true) = self.accounts.test_password(account, password) { - return Some(password.clone()); - } - } - None - } - } - } - - pub fn private_tx_signer( - accounts: Arc, - passwords: &[Password], - ) -> Result, String> { - Ok(Arc::new(self::private_tx::AccountSigner { - accounts, - passwords: passwords.to_vec(), - })) - } - pub fn accounts_list( account_provider: Arc, ) -> Arc Vec
+ Send + Sync> { @@ -318,6 +255,5 @@ mod accounts { } pub use self::accounts::{ - accounts_list, miner_author, miner_local_accounts, prepare_account_provider, private_tx_signer, - AccountProvider, + accounts_list, miner_author, miner_local_accounts, prepare_account_provider, AccountProvider, }; diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 6940a56e2..986bfb7b3 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -29,7 +29,6 @@ use ethcore::{ miner::Miner, verification::queue::VerifierSettings, }; -use ethcore_private_tx; use ethcore_service::ClientService; use ethereum_types::{Address, H256, U256}; use hash::{keccak, KECCAK_NULL_RLP}; @@ -211,10 +210,6 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { // TODO [ToDr] don't use test miner here // (actually don't require miner at all) Arc::new(Miner::new_for_tests(&spec, None)), - Arc::new(ethcore_private_tx::DummySigner), - Box::new(ethcore_private_tx::NoopEncryptor), - Default::default(), - Default::default(), ) .map_err(|e| format!("Client service error: {:?}", e))?; @@ -350,10 +345,6 @@ fn start_client( // It's fine to use test version here, // since we don't care about miner parameters at all Arc::new(Miner::new_for_tests(&spec, None)), - Arc::new(ethcore_private_tx::DummySigner), - Box::new(ethcore_private_tx::NoopEncryptor), - Default::default(), - Default::default(), ) .map_err(|e| format!("Client service error: {:?}", e))?; diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 3c6aa99a7..0aa86023f 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -300,35 +300,6 @@ usage! { "--password=[FILE]...", "Provide a file containing a password for unlocking an account. Leading and trailing whitespace is trimmed.", - ["Private Transactions Options"] - FLAG flag_private_enabled: (bool) = false, or |c: &Config| c.private_tx.as_ref()?.enabled, - "--private-tx-enabled", - "Enable private transactions.", - - ARG arg_private_signer: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.signer.clone(), - "--private-signer=[ACCOUNT]", - "Specify the account for signing public transaction created upon verified private transaction.", - - ARG arg_private_validators: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.validators.as_ref().map(|vec| vec.join(",")), - "--private-validators=[ACCOUNTS]", - "Specify the accounts for validating private transactions. ACCOUNTS is a comma-delimited list of addresses.", - - ARG arg_private_account: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.account.clone(), - "--private-account=[ACCOUNT]", - "Specify the account for signing requests to secret store.", - - ARG arg_private_sstore_url: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.sstore_url.clone(), - "--private-sstore-url=[URL]", - "Specify secret store URL used for encrypting private transactions.", - - ARG arg_private_sstore_threshold: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.sstore_threshold.clone(), - "--private-sstore-threshold=[NUM]", - "Specify secret store threshold used for encrypting private transactions.", - - ARG arg_private_passwords: (Option) = None, or |c: &Config| c.private_tx.as_ref()?.passwords.clone(), - "--private-passwords=[FILE]...", - "Provide a file containing passwords for unlocking accounts (signer, private account, validators).", - ["UI Options"] ARG arg_ui_path: (String) = "$BASE/signer", or |c: &Config| c.ui.as_ref()?.path.clone(), "--ui-path=[PATH]", @@ -438,7 +409,7 @@ usage! { "--jsonrpc-interface=[IP]", "Specify the hostname portion of the HTTP JSON-RPC API server, IP should be an interface's IP address, or all (all interfaces) or local.", - ARG arg_jsonrpc_apis: (String) = "web3,eth,pubsub,net,parity,private,parity_pubsub,traces", or |c: &Config| c.rpc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), + ARG arg_jsonrpc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces", or |c: &Config| c.rpc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), "--jsonrpc-apis=[APIS]", "Specify the APIs available through the HTTP JSON-RPC interface using a comma-delimited list of API names. Possible names are: all, safe, debug, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces", @@ -479,7 +450,7 @@ usage! { "--ws-interface=[IP]", "Specify the hostname portion of the WebSockets JSON-RPC server, IP should be an interface's IP address, or all (all interfaces) or local.", - ARG arg_ws_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,private,traces", or |c: &Config| c.websockets.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), + ARG arg_ws_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,traces", or |c: &Config| c.websockets.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), "--ws-apis=[APIS]", "Specify the JSON-RPC APIs available through the WebSockets interface using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces", @@ -504,7 +475,7 @@ usage! { "--ipc-path=[PATH]", "Specify custom path for JSON-RPC over IPC service.", - ARG arg_ipc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,private,traces", or |c: &Config| c.ipc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), + ARG arg_ipc_apis: (String) = "web3,eth,pubsub,net,parity,parity_pubsub,parity_accounts,traces", or |c: &Config| c.ipc.as_ref()?.apis.as_ref().map(|vec| vec.join(",")), "--ipc-apis=[APIS]", "Specify custom API set available via JSON-RPC over IPC using a comma-delimited list of API names. Possible names are: all, safe, web3, net, eth, pubsub, personal, signer, parity, parity_pubsub, parity_accounts, parity_set, traces, secretstore. You can also disable a specific API by putting '-' in the front, example: all,-personal. 'safe' enables the following APIs: web3, net, eth, pubsub, parity, parity_pubsub, traces", @@ -832,7 +803,6 @@ struct Config { websockets: Option, ipc: Option, secretstore: Option, - private_tx: Option, mining: Option, footprint: Option, snapshots: Option, @@ -864,18 +834,6 @@ struct Account { fast_unlock: Option, } -#[derive(Default, Debug, PartialEq, Deserialize)] -#[serde(deny_unknown_fields)] -struct PrivateTransactions { - enabled: Option, - signer: Option, - validators: Option>, - account: Option, - passwords: Option, - sstore_url: Option, - sstore_threshold: Option, -} - #[derive(Default, Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] struct Ui { @@ -1297,15 +1255,6 @@ mod tests { arg_accounts_refresh: 5u64, flag_fast_unlock: false, - // -- Private Transactions Options - flag_private_enabled: true, - arg_private_signer: Some("0xdeadbeefcafe0000000000000000000000000000".into()), - arg_private_validators: Some("0xdeadbeefcafe0000000000000000000000000000".into()), - arg_private_passwords: Some("~/.safe/password.file".into()), - arg_private_account: Some("0xdeadbeefcafe0000000000000000000000000000".into()), - arg_private_sstore_url: Some("http://localhost:8082".into()), - arg_private_sstore_threshold: Some(0), - arg_ui_path: "$HOME/.parity/signer".into(), // -- Networking Options @@ -1576,7 +1525,6 @@ mod tests { http_port: Some(8082), path: None, }), - private_tx: None, mining: Some(Mining { author: Some("0xdeadbeefcafe0000000000000000000000000001".into()), engine_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), diff --git a/parity/cli/tests/config.full.toml b/parity/cli/tests/config.full.toml index d59dd3553..87da3c919 100644 --- a/parity/cli/tests/config.full.toml +++ b/parity/cli/tests/config.full.toml @@ -15,15 +15,6 @@ unlock = ["0xdeadbeefcafe0000000000000000000000000000"] password = ["~/.safe/password.file"] keys_iterations = 10240 -[private_tx] -enabled = true -signer = "0xdeadbeefcafe0000000000000000000000000000" -validators = ["0xdeadbeefcafe0000000000000000000000000000"] -passwords = "~/.safe/password.file" -account = "0xdeadbeefcafe0000000000000000000000000000" -sstore_url = "http://localhost:8082" -sstore_threshold = 0 - [ui] path = "$HOME/.parity/signer" diff --git a/parity/configuration.rs b/parity/configuration.rs index c1f85570a..6ca82a32a 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -52,7 +52,6 @@ use dir::{ Directories, }; use ethcore_logger::Config as LogConfig; -use ethcore_private_tx::{EncryptorConfig, ProviderConfig}; use helpers::{ parity_ipc_path, to_address, to_addresses, to_block_id, to_bootnodes, to_duration, to_mode, to_pending_set, to_price, to_queue_penalization, to_queue_strategy, to_u256, @@ -382,8 +381,6 @@ impl Configuration { }; let verifier_settings = self.verifier_settings(); - let (private_provider_conf, private_enc_conf, private_tx_enabled) = - self.private_provider_config()?; let run_cmd = RunCmd { cache_config: cache_config, @@ -418,9 +415,6 @@ impl Configuration { experimental_rpcs, net_settings: self.network_settings()?, secretstore_conf: secretstore_conf, - private_provider_conf: private_provider_conf, - private_encryptor_conf: private_enc_conf, - private_tx_enabled, name: self.args.arg_identity, custom_bootnodes: self.args.arg_bootnodes.is_some(), check_seal: !self.args.flag_no_seal_check, @@ -959,33 +953,6 @@ impl Configuration { Ok(conf) } - fn private_provider_config(&self) -> Result<(ProviderConfig, EncryptorConfig, bool), String> { - let provider_conf = ProviderConfig { - validator_accounts: to_addresses(&self.args.arg_private_validators)?, - signer_account: self - .args - .arg_private_signer - .clone() - .and_then(|account| to_address(Some(account)).ok()), - }; - - let encryptor_conf = EncryptorConfig { - base_url: self.args.arg_private_sstore_url.clone(), - threshold: self.args.arg_private_sstore_threshold.unwrap_or(0), - key_server_account: self - .args - .arg_private_account - .clone() - .and_then(|account| to_address(Some(account)).ok()), - }; - - Ok(( - provider_conf, - encryptor_conf, - self.args.flag_private_enabled, - )) - } - fn snapshot_config(&self) -> Result { let conf = SnapshotConfiguration { no_periodic: self.args.flag_no_periodic_snapshot, @@ -1554,9 +1521,6 @@ mod tests { experimental_rpcs: false, net_settings: Default::default(), secretstore_conf: Default::default(), - private_provider_conf: Default::default(), - private_encryptor_conf: Default::default(), - private_tx_enabled: false, name: "".into(), custom_bootnodes: false, fat_db: Default::default(), diff --git a/parity/lib.rs b/parity/lib.rs index 1a283f03b..863ba1cab 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -49,7 +49,6 @@ extern crate ethcore_io as io; extern crate ethcore_logger; extern crate ethcore_miner as miner; extern crate ethcore_network as network; -extern crate ethcore_private_tx; extern crate ethcore_service; extern crate ethcore_sync as sync; extern crate ethereum_types; diff --git a/parity/modules.rs b/parity/modules.rs index 023797a3f..b553bc45a 100644 --- a/parity/modules.rs +++ b/parity/modules.rs @@ -21,7 +21,7 @@ use sync::{self, ConnectionFilter, NetworkConfiguration, Params, SyncConfig}; pub use ethcore::client::ChainNotify; use ethcore_logger::Config as LogConfig; -pub use sync::{EthSync, ManageNetwork, PrivateTxHandler, SyncProvider}; +pub use sync::{EthSync, ManageNetwork, SyncProvider}; pub type SyncModules = ( Arc, @@ -35,7 +35,6 @@ pub fn sync( network_config: NetworkConfiguration, chain: Arc, snapshot_service: Arc, - private_tx_handler: Option>, _log_settings: &LogConfig, connection_filter: Option>, ) -> Result { @@ -44,7 +43,6 @@ pub fn sync( config, chain, snapshot_service, - private_tx_handler, network_config, }, connection_filter, diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 3f02bfa09..5cffa656f 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -21,7 +21,6 @@ pub use parity_rpc::signer::SignerService; use account_utils::{self, AccountProvider}; use ethcore::{client::Client, miner::Miner, snapshot::SnapshotService}; use ethcore_logger::RotatingLogger; -use ethcore_service::PrivateTxService; use fetch::Client as FetchClient; use jsonrpc_core::{self as core, MetaIoHandler}; use miner::external::ExternalMiner; @@ -52,8 +51,6 @@ pub enum Api { Parity, /// Traces (Safe) Traces, - /// Private transaction manager (Safe) - Private, /// Parity PubSub - Generic Publish-Subscriber (Safety depends on other APIs exposed). ParityPubSub, /// Parity Accounts extensions (UNSAFE: Passwords, Side Effects (new account)) @@ -82,7 +79,6 @@ impl FromStr for Api { "parity_pubsub" => Ok(ParityPubSub), "parity_set" => Ok(ParitySet), "personal" => Ok(Personal), - "private" => Ok(Private), "pubsub" => Ok(EthPubSub), "secretstore" => Ok(SecretStore), "signer" => Ok(Signer), @@ -191,7 +187,6 @@ pub struct FullDependencies { pub sync: Arc, pub net: Arc, pub accounts: Arc, - pub private_tx_service: Option>, pub miner: Arc, pub external_miner: Arc, pub logger: Arc, @@ -385,12 +380,6 @@ impl FullDependencies { #[cfg(feature = "accounts")] handler.extend_with(SecretStoreClient::new(&self.accounts).to_delegate()); } - Api::Private => { - handler.extend_with( - PrivateClient::new(self.private_tx_service.as_ref().map(|p| p.provider())) - .to_delegate(), - ); - } } } } @@ -420,17 +409,11 @@ impl ApiSet { } pub fn list_apis(&self) -> HashSet { - let mut public_list: HashSet = [ - Api::Web3, - Api::Net, - Api::Eth, - Api::EthPubSub, - Api::Parity, - Api::Private, - ] - .iter() - .cloned() - .collect(); + let mut public_list: HashSet = + [Api::Web3, Api::Net, Api::Eth, Api::EthPubSub, Api::Parity] + .iter() + .cloned() + .collect(); match *self { ApiSet::List(ref apis) => apis.clone(), @@ -488,7 +471,6 @@ mod test { assert_eq!(Api::ParitySet, "parity_set".parse().unwrap()); assert_eq!(Api::Traces, "traces".parse().unwrap()); assert_eq!(Api::SecretStore, "secretstore".parse().unwrap()); - assert_eq!(Api::Private, "private".parse().unwrap()); assert!("rp".parse::().is_err()); } @@ -516,7 +498,6 @@ mod test { Api::Parity, Api::ParityPubSub, Api::Traces, - Api::Private, ] .into_iter() .collect(); @@ -534,7 +515,6 @@ mod test { Api::Parity, Api::ParityPubSub, Api::Traces, - Api::Private, // semi-safe Api::ParityAccounts, ] @@ -561,7 +541,6 @@ mod test { Api::ParitySet, Api::Signer, Api::Personal, - Api::Private, Api::Debug, ] .into_iter() @@ -587,7 +566,6 @@ mod test { Api::ParityAccounts, Api::ParitySet, Api::Signer, - Api::Private, Api::Debug, ] .into_iter() @@ -609,7 +587,6 @@ mod test { Api::Parity, Api::ParityPubSub, Api::Traces, - Api::Private, ] .into_iter() .collect() diff --git a/parity/run.rs b/parity/run.rs index 0ac85a0e6..9c263fca7 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -33,7 +33,6 @@ use ethcore::{ verification::queue::VerifierSettings, }; use ethcore_logger::{Config as LogConfig, RotatingLogger}; -use ethcore_private_tx::{EncryptorConfig, ProviderConfig, SecretStoreEncryptor}; use ethcore_service::ClientService; use helpers::{execute_upgrades, passwords_from_files, to_client_config}; use informant::{FullNodeInformantData, Informant}; @@ -56,7 +55,7 @@ use rpc; use rpc_apis; use secretstore; use signer; -use sync::{self, PrivateTxHandler, SyncConfig}; +use sync::{self, SyncConfig}; use user_defaults::UserDefaults; // how often to take periodic snapshots. @@ -100,9 +99,6 @@ pub struct RunCmd { pub experimental_rpcs: bool, pub net_settings: NetworkSettings, pub secretstore_conf: secretstore::Configuration, - pub private_provider_conf: ProviderConfig, - pub private_encryptor_conf: EncryptorConfig, - pub private_tx_enabled: bool, pub name: String, pub custom_bootnodes: bool, pub stratum: Option, @@ -348,8 +344,6 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result) -> Result) -> Result, @@ -446,18 +426,12 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result> = match cmd.private_tx_enabled { - true => Some(private_tx_service.clone() as Arc), - false => None, - }; - // create sync object let (sync_provider, manage_network, chain_notify, priority_tasks) = modules::sync( sync_config, net_conf.clone().into(), client.clone(), snapshot_service.clone(), - private_tx_sync, &cmd.logger_config, connection_filter .clone() @@ -480,15 +454,6 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result) -> Result) -> Error { } } -pub fn light_unimplemented(details: Option) -> Error { - Error { - code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), - message: "This request is unsupported for light clients.".into(), - data: details.map(Value::String), - } -} - pub fn unsupported>(msg: T, details: Option) -> Error { Error { code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), @@ -374,22 +364,6 @@ pub fn password(error: ::accounts::SignError) -> Error { } } -pub fn private_message(error: PrivateTransactionError) -> Error { - Error { - code: ErrorCode::ServerError(codes::PRIVATE_ERROR), - message: "Private transactions call failed.".into(), - data: Some(Value::String(format!("{:?}", error))), - } -} - -pub fn private_message_block_id_not_supported() -> Error { - Error { - code: ErrorCode::ServerError(codes::PRIVATE_ERROR), - message: "Pending block id not supported.".into(), - data: None, - } -} - pub fn transaction_message(error: &TransactionError) -> String { use self::TransactionError::*; diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index cea888543..afa2a2202 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -27,7 +27,6 @@ mod parity_accounts; mod parity_set; #[cfg(any(test, feature = "accounts"))] mod personal; -mod private; mod pubsub; #[cfg(any(test, feature = "accounts"))] mod secretstore; @@ -53,7 +52,6 @@ pub use self::{ net::NetClient, parity::ParityClient, parity_set::ParitySetClient, - private::PrivateClient, pubsub::PubSubClient, signer::SignerClient, signing::SigningQueueClient, diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs deleted file mode 100644 index f5c6280fb..000000000 --- a/rpc/src/v1/impls/private.rs +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -//! Private transaction signing RPC implementation. - -use std::sync::Arc; - -use rlp::Rlp; - -use ethcore_private_tx::Provider as PrivateTransactionManager; -use ethereum_types::{Address, H160, H256, U256}; -use types::transaction::SignedTransaction; - -use jsonrpc_core::Error; -use v1::{ - helpers::{errors, fake_sign}, - metadata::Metadata, - traits::Private, - types::{ - block_number_to_id, BlockNumber, Bytes, CallRequest, PrivateTransactionReceipt, - PrivateTransactionReceiptAndTransaction, TransactionRequest, - }, -}; - -/// Private transaction manager API endpoint implementation. -pub struct PrivateClient { - private: Option>, -} - -impl PrivateClient { - /// Creates a new instance. - pub fn new(private: Option>) -> Self { - PrivateClient { private } - } - - fn unwrap_manager(&self) -> Result<&PrivateTransactionManager, Error> { - match self.private { - Some(ref arc) => Ok(&**arc), - None => Err(errors::light_unimplemented(None)), - } - } -} - -impl Private for PrivateClient { - type Metadata = Metadata; - - fn send_transaction(&self, request: Bytes) -> Result { - let signed_transaction = Rlp::new(&request.into_vec()) - .as_val() - .map_err(errors::rlp) - .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))?; - let client = self.unwrap_manager()?; - let receipt = client - .create_private_transaction(signed_transaction) - .map_err(errors::private_message)?; - Ok(receipt.into()) - } - - fn compose_deployment_transaction( - &self, - block_number: BlockNumber, - request: Bytes, - validators: Vec, - gas_price: U256, - ) -> Result { - let signed_transaction = Rlp::new(&request.into_vec()) - .as_val() - .map_err(errors::rlp) - .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))?; - let client = self.unwrap_manager()?; - - let addresses: Vec
= validators.into_iter().map(Into::into).collect(); - let id = match block_number { - BlockNumber::Pending => return Err(errors::private_message_block_id_not_supported()), - num => block_number_to_id(num), - }; - - let (transaction, contract_address) = client - .public_creation_transaction(id, &signed_transaction, addresses.as_slice(), gas_price) - .map_err(errors::private_message)?; - let tx_hash = transaction.hash(None); - let request = TransactionRequest { - from: Some(signed_transaction.sender()), - to: None, - nonce: Some(transaction.nonce), - gas_price: Some(transaction.gas_price), - gas: Some(transaction.gas), - value: Some(transaction.value), - data: Some(transaction.data.into()), - condition: None, - }; - - Ok(PrivateTransactionReceiptAndTransaction { - transaction: request, - receipt: PrivateTransactionReceipt { - transaction_hash: tx_hash, - contract_address, - status_code: 0, - }, - }) - } - - fn private_call( - &self, - block_number: BlockNumber, - request: CallRequest, - ) -> Result { - let id = match block_number { - BlockNumber::Pending => return Err(errors::private_message_block_id_not_supported()), - num => block_number_to_id(num), - }; - - let request = CallRequest::into(request); - let signed = fake_sign::sign_call(request)?; - let client = self.unwrap_manager()?; - let executed_result = client - .private_call(id, &signed) - .map_err(errors::private_message)?; - Ok(executed_result.output.into()) - } - - fn private_contract_key(&self, contract_address: H160) -> Result { - let client = self.unwrap_manager()?; - let key = client - .contract_key_id(&contract_address) - .map_err(errors::private_message)?; - Ok(key) - } -} diff --git a/rpc/src/v1/mod.rs b/rpc/src/v1/mod.rs index 40da30eb6..d570359fa 100644 --- a/rpc/src/v1/mod.rs +++ b/rpc/src/v1/mod.rs @@ -48,7 +48,7 @@ pub use self::{ metadata::Metadata, traits::{ Debug, Eth, EthFilter, EthPubSub, EthSigning, Net, Parity, ParityAccounts, - ParityAccountsInfo, ParitySet, ParitySetAccounts, ParitySigning, Personal, Private, PubSub, + ParityAccountsInfo, ParitySet, ParitySetAccounts, ParitySigning, Personal, PubSub, SecretStore, Signer, Traces, Web3, }, types::Origin, diff --git a/rpc/src/v1/traits/mod.rs b/rpc/src/v1/traits/mod.rs index 7c21db7bd..44dcc16bb 100644 --- a/rpc/src/v1/traits/mod.rs +++ b/rpc/src/v1/traits/mod.rs @@ -26,7 +26,6 @@ pub mod parity_accounts; pub mod parity_set; pub mod parity_signing; pub mod personal; -pub mod private; pub mod pubsub; pub mod secretstore; pub mod signer; @@ -44,7 +43,6 @@ pub use self::{ parity_set::{ParitySet, ParitySetAccounts}, parity_signing::ParitySigning, personal::Personal, - private::Private, pubsub::PubSub, secretstore::SecretStore, signer::Signer, diff --git a/rpc/src/v1/traits/private.rs b/rpc/src/v1/traits/private.rs deleted file mode 100644 index 8772079a6..000000000 --- a/rpc/src/v1/traits/private.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -//! SecretStore-specific rpc interface. - -use ethereum_types::{H160, H256, U256}; -use jsonrpc_core::Error; -use jsonrpc_derive::rpc; - -use v1::types::{ - BlockNumber, Bytes, CallRequest, PrivateTransactionReceipt, - PrivateTransactionReceiptAndTransaction, -}; - -/// Private transaction management RPC interface. -#[rpc(server)] -pub trait Private { - /// RPC Metadata - type Metadata; - - /// Sends private transaction; Transaction will be added to the validation queue and sent out when ready. - #[rpc(name = "private_sendTransaction")] - fn send_transaction(&self, _: Bytes) -> Result; - - /// Creates a transaction for contract's deployment from origin (signed transaction) - #[rpc(name = "private_composeDeploymentTransaction")] - fn compose_deployment_transaction( - &self, - _: BlockNumber, - _: Bytes, - _: Vec, - _: U256, - ) -> Result; - - /// Make a call to the private contract - #[rpc(name = "private_call")] - fn private_call(&self, _: BlockNumber, _: CallRequest) -> Result; - - /// Retrieve the id of the key associated with the contract - #[rpc(name = "private_contractKey")] - fn private_contract_key(&self, _: H160) -> Result; -} diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index dd95d0388..578dcfab1 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -32,7 +32,6 @@ mod histogram; mod index; mod log; mod node_kind; -mod private_receipt; mod provenance; mod receipt; mod rpc_settings; @@ -65,7 +64,6 @@ pub use self::{ index::Index, log::Log, node_kind::{Availability, Capability, NodeKind}, - private_receipt::{PrivateTransactionReceipt, PrivateTransactionReceiptAndTransaction}, provenance::Origin, receipt::Receipt, rpc_settings::RpcSettings, diff --git a/rpc/src/v1/types/private_receipt.rs b/rpc/src/v1/types/private_receipt.rs deleted file mode 100644 index 368a856d2..000000000 --- a/rpc/src/v1/types/private_receipt.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity Ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity Ethereum. If not, see . - -use ethcore_private_tx::Receipt as EthPrivateReceipt; -use ethereum_types::{H160, H256}; -use v1::types::TransactionRequest; - -/// Receipt -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct PrivateTransactionReceipt { - /// Transaction Hash - pub transaction_hash: H256, - /// Private contract address - pub contract_address: H160, - /// Status code - #[serde(rename = "status")] - pub status_code: u8, -} - -impl From for PrivateTransactionReceipt { - fn from(r: EthPrivateReceipt) -> Self { - PrivateTransactionReceipt { - transaction_hash: r.hash, - contract_address: r.contract_address, - status_code: r.status_code, - } - } -} - -/// Receipt and Transaction -#[derive(Debug, Serialize)] -pub struct PrivateTransactionReceiptAndTransaction { - /// Receipt - pub receipt: PrivateTransactionReceipt, - /// Transaction - pub transaction: TransactionRequest, -} diff --git a/util/fetch/src/client.rs b/util/fetch/src/client.rs index cdd00981f..a336b2465 100644 --- a/util/fetch/src/client.rs +++ b/util/fetch/src/client.rs @@ -479,11 +479,6 @@ impl Response { self.status() == StatusCode::OK } - /// Status code == 404. - pub fn is_not_found(&self) -> bool { - self.status() == StatusCode::NOT_FOUND - } - /// Is the content-type text/html? pub fn is_html(&self) -> bool { self.headers