From a3c1eea6f30bed1a9c006e70bc5900a0ea584f4f Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Thu, 17 Sep 2020 00:18:07 +1200 Subject: [PATCH 01/12] fix nonce hanlding and emit event on success execution (#130) --- frame/ethereum/src/lib.rs | 20 +++++++++++++------- frame/ethereum/src/mock.rs | 16 +++++----------- frame/ethereum/src/tests.rs | 24 +++++++++++++++++++----- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index 9d08d8f000..f605575a13 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -81,7 +81,10 @@ decl_storage! { decl_event!( /// Ethereum pallet events. - pub enum Event { } + pub enum Event { + /// An ethereum transaction was successfully executed. [from, transaction_hash] + Executed(H160, H256), + } ); @@ -149,7 +152,11 @@ decl_module! { let source = Self::recover_signer(&transaction).ok_or_else(|| Error::::InvalidSignature)?; + let hash = transaction.message_hash(Some(T::ChainId::get())); + Self::execute(source, transaction)?; + + Self::deposit_event(Event::Executed(source, hash)); } fn on_finalize(n: T::BlockNumber) { @@ -183,9 +190,6 @@ impl frame_support::unsigned::ValidateUnsigned for Module { if transaction.nonce < account_data.nonce { return InvalidTransaction::Stale.into(); } - if transaction.nonce > account_data.nonce { - return InvalidTransaction::Future.into(); - } let fee = transaction.gas_price.saturating_mul(transaction.gas_limit); @@ -194,10 +198,12 @@ impl frame_support::unsigned::ValidateUnsigned for Module { } let mut builder = ValidTransaction::with_tag_prefix("Ethereum") - .and_provides((&account_data, account_data.nonce)); + .and_provides((&origin, transaction.nonce)); - if let Some(prev_nonce) = account_data.nonce.checked_sub(1.into()) { - builder = builder.and_requires((account_data, prev_nonce)) + if transaction.nonce > account_data.nonce { + if let Some(prev_nonce) = transaction.nonce.checked_sub(1.into()) { + builder = builder.and_requires((origin, prev_nonce)) + } } builder.build() diff --git a/frame/ethereum/src/mock.rs b/frame/ethereum/src/mock.rs index 2f68b007de..e312201b39 100644 --- a/frame/ethereum/src/mock.rs +++ b/frame/ethereum/src/mock.rs @@ -235,7 +235,7 @@ impl UnsignedTransaction { s.append(&self.action); s.append(&self.value); s.append(&self.input); - s.append(&42u8); // TODO: move this chain id into the frame ethereum configuration + s.append(&ChainId::get()); s.append(&0u8); s.append(&0u8); } @@ -246,20 +246,14 @@ impl UnsignedTransaction { H256::from_slice(&Keccak256::digest(&stream.drain()).as_slice()) } - pub fn sign(self, key: &H256) -> Transaction { + pub fn sign(&self, key: &H256) -> Transaction { let hash = self.signing_hash(); - let msg = { - let mut a = [0u8; 32]; - for i in 0..32 { - a[i] = hash[i]; - } - secp256k1::Message::parse(&a) - }; + let msg = secp256k1::Message::parse(hash.as_fixed_bytes()); let s = secp256k1::sign(&msg, &secp256k1::SecretKey::parse_slice(&key[..]).unwrap()); let sig = s.0.serialize(); let sig = TransactionSignature::new( - 0x78, + s.1.serialize() as u64 % 2 + ChainId::get() * 2 + 35, H256::from_slice(&sig[0..32]), H256::from_slice(&sig[32..64]), ) @@ -271,7 +265,7 @@ impl UnsignedTransaction { gas_limit: self.gas_limit, action: self.action, value: self.value, - input: self.input, + input: self.input.clone(), signature: sig, } } diff --git a/frame/ethereum/src/tests.rs b/frame/ethereum/src/tests.rs index 0670cf30e2..21266213f8 100644 --- a/frame/ethereum/src/tests.rs +++ b/frame/ethereum/src/tests.rs @@ -37,7 +37,7 @@ use sp_runtime::transaction_validity::{TransactionSource, InvalidTransaction}; // } const ERC20_CONTRACT_BYTECODE: &str = "608060405234801561001057600080fd5b50610041337fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61004660201b60201c565b610291565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156100e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6101028160025461020960201b610c7c1790919060201c565b60028190555061015d816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461020960201b610c7c1790919060201c565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080828401905083811015610287576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b610e3a806102a06000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806370a082311161005b57806370a08231146101fd578063a457c2d714610255578063a9059cbb146102bb578063dd62ed3e1461032157610088565b8063095ea7b31461008d57806318160ddd146100f357806323b872dd146101115780633950935114610197575b600080fd5b6100d9600480360360408110156100a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610399565b604051808215151515815260200191505060405180910390f35b6100fb6103b7565b6040518082815260200191505060405180910390f35b61017d6004803603606081101561012757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506103c1565b604051808215151515815260200191505060405180910390f35b6101e3600480360360408110156101ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061049a565b604051808215151515815260200191505060405180910390f35b61023f6004803603602081101561021357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061054d565b6040518082815260200191505060405180910390f35b6102a16004803603604081101561026b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610595565b604051808215151515815260200191505060405180910390f35b610307600480360360408110156102d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610662565b604051808215151515815260200191505060405180910390f35b6103836004803603604081101561033757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610680565b6040518082815260200191505060405180910390f35b60006103ad6103a6610707565b848461070f565b6001905092915050565b6000600254905090565b60006103ce848484610906565b61048f846103da610707565b61048a85604051806060016040528060288152602001610d7060289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610440610707565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610bbc9092919063ffffffff16565b61070f565b600190509392505050565b60006105436104a7610707565b8461053e85600160006104b8610707565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7c90919063ffffffff16565b61070f565b6001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60006106586105a2610707565b8461065385604051806060016040528060258152602001610de160259139600160006105cc610707565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610bbc9092919063ffffffff16565b61070f565b6001905092915050565b600061067661066f610707565b8484610906565b6001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610795576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180610dbd6024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561081b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610d286022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561098c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180610d986025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610a12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610d056023913960400191505060405180910390fd5b610a7d81604051806060016040528060268152602001610d4a602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610bbc9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b10816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c7c90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290610c69576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610c2e578082015181840152602081019050610c13565b50505050905090810190601f168015610c5b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015610cfa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b809150509291505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820c7a5ffabf642bda14700b2de42f8c57b36621af020441df825de45fd2b3e1c5c64736f6c63430005100032"; -fn default_erc20_creation_transaction(account: &AccountInfo) -> Transaction { +fn default_erc20_creation_unsigned_transaction() -> UnsignedTransaction { UnsignedTransaction { nonce: U256::zero(), gas_price: U256::from(1), @@ -45,7 +45,11 @@ fn default_erc20_creation_transaction(account: &AccountInfo) -> Transaction { action: ethereum::TransactionAction::Create, value: U256::zero(), input: FromHex::from_hex(ERC20_CONTRACT_BYTECODE).unwrap(), - }.sign(&account.private_key) + } +} + +fn default_erc20_creation_transaction(account: &AccountInfo) -> Transaction { + default_erc20_creation_unsigned_transaction().sign(&account.private_key) } #[test] @@ -100,10 +104,18 @@ fn transaction_with_invalid_nonce_should_not_work() { ext.execute_with(|| { // nonce is 0 - let mut transaction = default_erc20_creation_transaction(alice); + let mut transaction = default_erc20_creation_unsigned_transaction(); transaction.nonce = U256::from(1); - assert_err!(Ethereum::validate_unsigned(TransactionSource::External, &Call::transact(transaction.clone())), InvalidTransaction::Future); + let signed = transaction.sign(&alice.private_key); + + assert_eq!( + Ethereum::validate_unsigned(TransactionSource::External, &Call::transact(signed)), + ValidTransaction::with_tag_prefix("Ethereum") + .and_provides((&alice.address, U256::from(1))) + .and_requires((&alice.address, U256::from(0))) + .build() + ); // nonce is 1 assert_ok!(Ethereum::execute( @@ -113,7 +125,9 @@ fn transaction_with_invalid_nonce_should_not_work() { transaction.nonce = U256::from(0); - assert_err!(Ethereum::validate_unsigned(TransactionSource::External, &Call::transact(transaction)), InvalidTransaction::Stale); + let signed2 = transaction.sign(&alice.private_key); + + assert_err!(Ethereum::validate_unsigned(TransactionSource::External, &Call::transact(signed2)), InvalidTransaction::Stale); }); } From 9a73627512a9dc2652d35feb2e087395d98caec8 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 16 Sep 2020 15:14:25 +0200 Subject: [PATCH 02/12] Add CODEOWNERS (#131) * Add CODEOWNERS * Add comments on what CODEOWNERS mean --- .github/CODEOWNERS | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..ae20e673b5 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# A codeowner just oversees some part of the codebase. If an owned file is changed then the +# corresponding codeowner receives a review request. An approval of the codeowner is +# not required for merging a PR. + +* @sorpaas From 0cbe438c440384b0e4864e156c6a4046ca752fef Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Sun, 20 Sep 2020 21:58:21 +0200 Subject: [PATCH 03/12] Replace vendor ethereum with published ethereum crate and fix warnings (#138) * Remove ethereum vendor * Update ethereum dependency and fix most warnings --- .gitmodules | 3 --- Cargo.lock | 6 ++++-- Cargo.toml | 5 +---- consensus/Cargo.toml | 2 +- frame/ethereum/Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- rpc/core/src/eth.rs | 2 +- rpc/primitives/Cargo.toml | 2 +- rpc/primitives/src/lib.rs | 3 +-- rpc/src/lib.rs | 9 +-------- template/node/Cargo.toml | 2 +- template/node/src/rpc.rs | 2 +- template/runtime/src/lib.rs | 1 - vendor/ethereum | 1 - 14 files changed, 14 insertions(+), 28 deletions(-) delete mode 160000 vendor/ethereum diff --git a/.gitmodules b/.gitmodules index 8a7c8a4ae3..e69de29bb2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "vendor/ethereum"] - path = vendor/ethereum - url = https://github.com/rust-blockchain/ethereum diff --git a/Cargo.lock b/Cargo.lock index 543a72b8bd..d4255584f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1131,7 +1131,9 @@ dependencies = [ [[package]] name = "ethereum" -version = "0.2.0" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f873613a1191fe9d63794b5d0b636712446153ef0df192e9381bf1f951d3b94" dependencies = [ "ethereum-types", "parity-scale-codec", @@ -1544,7 +1546,7 @@ dependencies = [ "futures 0.3.5", "jsonrpc-core", "log", - "pallet-ethereum 0.1.0", + "pallet-ethereum 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-evm", "pallet-transaction-payment-rpc", "sc-basic-authorship", diff --git a/Cargo.toml b/Cargo.toml index 8c6cef3d3e..f9b714d3d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,4 @@ members = [ "template/runtime", "template/test-utils/client", ] -exclude = ["vendor"] - -[patch.crates-io] -ethereum = { path = "vendor/ethereum" } \ No newline at end of file +exclude = ["vendor"] \ No newline at end of file diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 0adb7af789..3ce3a60a6c 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -23,4 +23,4 @@ futures = { version = "0.3.1", features = ["compat"] } sp-timestamp = { version = "2.0.0-rc6", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } derive_more = "0.99.2" prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate.git", branch = "frontier"} -ethereum = { version = "0.2", features = ["codec"], path = "../vendor/ethereum/" } \ No newline at end of file +ethereum = { version = "0.3", features = ["codec"] } \ No newline at end of file diff --git a/frame/ethereum/Cargo.toml b/frame/ethereum/Cargo.toml index 47ddfcf938..0ef156620d 100644 --- a/frame/ethereum/Cargo.toml +++ b/frame/ethereum/Cargo.toml @@ -19,7 +19,7 @@ sp-runtime = { version = "2.0.0-dev", default-features = false, git = "https://g sp-std = { version = "2.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-io = { version = "2.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "frontier" } evm = { version = "0.17.0", default-features = false } -ethereum = { version = "0.2", default-features = false, features = ["codec"], path = "../../vendor/ethereum/" } +ethereum = { version = "0.3", default-features = false, features = ["codec"] } ethereum-types = { version = "0.9", default-features = false } rlp = { version = "0.4", default-features = false } sha3 = { version = "0.8", default-features = false } diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index b32373be81..1f29d55cdb 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -22,7 +22,7 @@ sp-transaction-pool = { git = "https://github.com/paritytech/substrate.git", bra sp-storage = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sc-service = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sc-client-api = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } -ethereum = { version = "0.2", features = ["codec"], path = "../vendor/ethereum/" } +ethereum = { version = "0.3", features = ["codec"] } codec = { package = "parity-scale-codec", version = "1.0.0" } rlp = "0.4" pallet-ethereum = "0.1" diff --git a/rpc/core/src/eth.rs b/rpc/core/src/eth.rs index ab31d94451..eb8a579f5d 100644 --- a/rpc/core/src/eth.rs +++ b/rpc/core/src/eth.rs @@ -21,7 +21,7 @@ use jsonrpc_core::{BoxFuture, Result}; use jsonrpc_derive::rpc; use crate::types::{ - BlockNumber, Bytes, CallRequest, EthAccount, Filter, FilterChanges, Index, Log, Receipt, + BlockNumber, Bytes, CallRequest, Filter, FilterChanges, Index, Log, Receipt, RichBlock, SyncStatus, Transaction, Work, }; pub use rpc_impl_EthApi::gen_server::EthApi as EthApiServer; diff --git a/rpc/primitives/Cargo.toml b/rpc/primitives/Cargo.toml index f6c34e7d7d..b7869183a1 100644 --- a/rpc/primitives/Cargo.toml +++ b/rpc/primitives/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0" sp-core = { version = "2.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-api = { version = "2.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "frontier" } pallet-evm = { version = "2.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "frontier" } -ethereum = { version = "0.2", default-features = false, features = ["codec"], path = "../../vendor/ethereum/" } +ethereum = { version = "0.3", default-features = false, features = ["codec"] } ethereum-types = { version = "0.9", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } sp-runtime = { version = "2.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "frontier" } diff --git a/rpc/primitives/src/lib.rs b/rpc/primitives/src/lib.rs index 05b6667899..fadbcbceaa 100644 --- a/rpc/primitives/src/lib.rs +++ b/rpc/primitives/src/lib.rs @@ -18,8 +18,7 @@ use sp_core::{H160, H256, U256}; use ethereum::{ - Log, Block as EthereumBlock, Transaction as EthereumTransaction, - Receipt as EthereumReceipt, TransactionAction + Log, Block as EthereumBlock, TransactionAction }; use ethereum_types::Bloom; use codec::{Encode, Decode}; diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index d2712d9f6d..c9e84a9738 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -30,7 +30,7 @@ use sha3::{Keccak256, Digest}; use sp_runtime::traits::BlakeTwo256; use frontier_rpc_core::{EthApi as EthApiT, NetApi as NetApiT}; use frontier_rpc_core::types::{ - BlockNumber, Bytes, CallRequest, EthAccount, Filter, Index, Log, Receipt, RichBlock, + BlockNumber, Bytes, CallRequest, Filter, Index, Log, Receipt, RichBlock, SyncStatus, SyncInfo, Transaction, Work, Rich, Block, BlockTransactions, VariadicValue }; use frontier_rpc_primitives::{EthereumRuntimeRPCApi, ConvertTransaction, TransactionStatus}; @@ -44,13 +44,6 @@ fn internal_err(message: T) -> Error { data: None } } -fn not_supported_err(message: &str) -> Error { - Error { - code: ErrorCode::InvalidRequest, - message: message.to_string(), - data: None - } -} pub struct EthApi { pool: Arc

, diff --git a/template/node/Cargo.toml b/template/node/Cargo.toml index 8a48025ac8..07e5dfb28f 100644 --- a/template/node/Cargo.toml +++ b/template/node/Cargo.toml @@ -39,7 +39,7 @@ sp-consensus = { version = "0.8.0-dev", git = "https://github.com/paritytech/sub sc-consensus = { version = "0.8.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-timestamp = { version = "2.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "frontier" } evm = { version = "2.0.0-dev", package = "pallet-evm", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } -ethereum = { version = "0.1.0", package = "pallet-ethereum", path = "../../frame/ethereum" } +ethereum = { version = "0.1.0", package = "pallet-ethereum" } sc-finality-grandpa = { version = "0.8.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-finality-grandpa = { version = "2.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sc-client-api = { version = "2.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } diff --git a/template/node/src/rpc.rs b/template/node/src/rpc.rs index b5b10b9a70..929a733f67 100644 --- a/template/node/src/rpc.rs +++ b/template/node/src/rpc.rs @@ -21,7 +21,7 @@ use std::{sync::Arc, fmt}; use sc_consensus_manual_seal::rpc::{ManualSeal, ManualSealApi}; use frontier_template_runtime::{Hash, AccountId, Index, opaque::Block, Balance}; -use sp_api::{ProvideRuntimeApi, Core}; +use sp_api::ProvideRuntimeApi; use sp_transaction_pool::TransactionPool; use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; use sp_consensus::SelectChain; diff --git a/template/runtime/src/lib.rs b/template/runtime/src/lib.rs index 0c037761ee..3dabe3f03f 100644 --- a/template/runtime/src/lib.rs +++ b/template/runtime/src/lib.rs @@ -59,7 +59,6 @@ pub use frame_support::{ }, ConsensusEngineId, }; -use frame_ethereum::{Block as EthereumBlock, Transaction as EthereumTransaction, Receipt as EthereumReceipt}; use frame_evm::{Account as EVMAccount, FeeCalculator, HashedAddressMapping, EnsureAddressTruncated}; use frontier_rpc_primitives::{TransactionStatus}; pub type BlockNumber = u32; diff --git a/vendor/ethereum b/vendor/ethereum deleted file mode 160000 index 4fdd3c8ac8..0000000000 --- a/vendor/ethereum +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4fdd3c8ac849f91f5352bc7dfc189144a09aac1e From b75f49225639734d4ff1c1c9c4137ab7a95d7ec6 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Sun, 20 Sep 2020 21:58:44 +0200 Subject: [PATCH 04/12] fix ts-test genesis block (#136) --- ts-tests/frontier-test-specs/simple-specs.json | 1 + ts-tests/tests/test-block.ts | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ts-tests/frontier-test-specs/simple-specs.json b/ts-tests/frontier-test-specs/simple-specs.json index 5940a6f6cd..d8f974b71b 100644 --- a/ts-tests/frontier-test-specs/simple-specs.json +++ b/ts-tests/frontier-test-specs/simple-specs.json @@ -24,6 +24,7 @@ "palletSudo": { "key": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" }, + "frameEthereum": {}, "frameEvm": { "accounts": { "0x6be02d1d3665660d22ff9624b7be0551ee1ac91b": { diff --git a/ts-tests/tests/test-block.ts b/ts-tests/tests/test-block.ts index 787f23df8d..ea5b0a91ea 100644 --- a/ts-tests/tests/test-block.ts +++ b/ts-tests/tests/test-block.ts @@ -13,12 +13,12 @@ describeWithFrontier("Frontier RPC (Block)", `simple-specs.json`, (context) => { expect(await context.web3.eth.getBlockNumber()).to.equal(0); }); - it.skip("should return genesis block", async function () { + it("should return genesis block", async function () { expect(await context.web3.eth.getBlockNumber()).to.equal(0); const block = await context.web3.eth.getBlock(0); expect(block).to.include({ - author: "0x0000000000000000000000000000001234567890", + author: "0x0000000000000000000000000000000000000000", difficulty: "0", extraData: "0x0000000000000000000000000000000000000000000000000000000000000000", gasLimit: 0, @@ -26,12 +26,12 @@ describeWithFrontier("Frontier RPC (Block)", `simple-specs.json`, (context) => { //hash: "0x14fe6f7c93597f79b901f8b5d7a84277a90915b8d355959b587e18de34f1dc17", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - miner: "0x0000000000000000000000000000001234567890", - number: 1, + miner: "0x0000000000000000000000000000000000000000", + number: 0, //parentHash: "0x2cc74f91423ba20e9bb0b2c7d8924eacd14bc98aa1daad078f8844e529221cde", receiptsRoot: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", sha3Uncles: "0x0000000000000000000000000000000000000000000000000000000000000000", - size: 539, + size: 533, stateRoot: "0x0000000000000000000000000000000000000000000000000000000000000000", //timestamp: 1595012243836, totalDifficulty: null, From b48c834589444c518c91bf39d0c9d253dae6b3b8 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Sun, 20 Sep 2020 21:59:14 +0200 Subject: [PATCH 05/12] include FrontierBlockImport when doing manual sealing (#134) * include FrontierBlockImport when doing manual sealing to store ethereum block_hash and transactions into AuxStore * fix --- template/node/src/service.rs | 28 +++++++++++++++---------- ts-tests/tests/test-block.ts | 11 ++++++++++ ts-tests/tests/test-contract-methods.ts | 9 ++++++++ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/template/node/src/service.rs b/template/node/src/service.rs index 778fc94ffa..5bc361d11c 100644 --- a/template/node/src/service.rs +++ b/template/node/src/service.rs @@ -27,7 +27,7 @@ type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; pub enum ConsensusResult { - Aura(( + Aura( sc_consensus_aura::AuraBlockImport< Block, FullClient, @@ -39,8 +39,8 @@ pub enum ConsensusResult { AuraPair >, sc_finality_grandpa::LinkHalf - )), - ManualSeal + ), + ManualSeal(FrontierBlockImport, FullClient>) } pub fn new_partial(config: &Configuration, manual_seal: bool) -> Result< @@ -71,8 +71,14 @@ pub fn new_partial(config: &Configuration, manual_seal: bool) -> Result< .map_err(Into::into) .map_err(sp_consensus::error::Error::InherentData)?; + let frontier_block_import = FrontierBlockImport::new( + client.clone(), + client.clone(), + true, + ); + let import_queue = sc_consensus_manual_seal::import_queue( - Box::new(client.clone()), + Box::new(frontier_block_import.clone()), &task_manager.spawn_handle(), config.prometheus_registry(), ); @@ -80,7 +86,7 @@ pub fn new_partial(config: &Configuration, manual_seal: bool) -> Result< return Ok(sc_service::PartialComponents { client, backend, task_manager, import_queue, keystore, select_chain, transaction_pool, inherent_data_providers, - other: ConsensusResult::ManualSeal + other: ConsensusResult::ManualSeal(frontier_block_import) }) } @@ -113,7 +119,7 @@ pub fn new_partial(config: &Configuration, manual_seal: bool) -> Result< Ok(sc_service::PartialComponents { client, backend, task_manager, import_queue, keystore, select_chain, transaction_pool, inherent_data_providers, - other: ConsensusResult::Aura((aura_block_import, grandpa_link)) + other: ConsensusResult::Aura(aura_block_import, grandpa_link) }) } @@ -126,7 +132,7 @@ pub fn new_full(config: Configuration, manual_seal: bool) -> Result { + ConsensusResult::ManualSeal(_) => { sc_service::build_network(sc_service::BuildNetworkParams { config: &config, client: client.clone(), @@ -139,7 +145,7 @@ pub fn new_full(config: Configuration, manual_seal: bool) -> Result { + ConsensusResult::Aura(_, _) => { sc_service::build_network(sc_service::BuildNetworkParams { config: &config, client: client.clone(), @@ -203,7 +209,7 @@ pub fn new_full(config: Configuration, manual_seal: bool) -> Result { + ConsensusResult::ManualSeal(block_import) => { if role.is_authority() { let env = sc_basic_authorship::ProposerFactory::new( client.clone(), @@ -214,7 +220,7 @@ pub fn new_full(config: Configuration, manual_seal: bool) -> Result Result { + ConsensusResult::Aura(aura_block_import, grandpa_link) => { if role.is_authority() { let proposer = sc_basic_authorship::ProposerFactory::new( client.clone(), diff --git a/ts-tests/tests/test-block.ts b/ts-tests/tests/test-block.ts index ea5b0a91ea..e92b722f57 100644 --- a/ts-tests/tests/test-block.ts +++ b/ts-tests/tests/test-block.ts @@ -106,6 +106,17 @@ describeWithFrontier("Frontier RPC (Block)", `simple-specs.json`, (context) => { expect(block.timestamp).to.be.a("number"); }); + step("get block by hash", async function() { + const latest_block = await context.web3.eth.getBlock("latest"); + const block = await context.web3.eth.getBlock(latest_block.hash); + expect(block.hash).to.be.eq(latest_block.hash); + }); + + step("get block by number", async function() { + const block = await context.web3.eth.getBlock(1); + expect(block).not.null; + }); + it.skip("should include previous block hash as parent", async function () { this.timeout(15000); await createAndFinalizeBlock(context.web3); diff --git a/ts-tests/tests/test-contract-methods.ts b/ts-tests/tests/test-contract-methods.ts index 525f6bed0f..6b36029f57 100644 --- a/ts-tests/tests/test-contract-methods.ts +++ b/ts-tests/tests/test-contract-methods.ts @@ -39,6 +39,15 @@ describeWithFrontier("Frontier RPC (Contract Methods)", `simple-specs.json`, (co await createAndFinalizeBlock(context.web3); }); + it("get transaction by hash", async () => { + const latestBlock = await context.web3.eth.getBlock("latest"); + expect(latestBlock.transactions.length).to.equal(1); + + const tx_hash = latestBlock.transactions[0]; + const tx = await context.web3.eth.getTransaction(tx_hash); + expect(tx.hash).to.equal(tx_hash); + }); + it("should return contract method result", async function () { const contract = new context.web3.eth.Contract([TEST_CONTRACT_ABI], FIRST_CONTRACT_ADDRESS, { from: GENESIS_ACCOUNT, From c893936ec3d7a5bc77d7bf82bb7aab7350544afb Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Sun, 20 Sep 2020 21:59:27 +0200 Subject: [PATCH 06/12] Add the four basic precompiles to frontier-template runtime (#132) --- template/runtime/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/template/runtime/src/lib.rs b/template/runtime/src/lib.rs index 3dabe3f03f..dc97fec24f 100644 --- a/template/runtime/src/lib.rs +++ b/template/runtime/src/lib.rs @@ -297,7 +297,12 @@ impl frame_evm::Trait for Runtime { type AddressMapping = HashedAddressMapping; type Currency = Balances; type Event = Event; - type Precompiles = (); + type Precompiles = ( + frame_evm::precompiles::ECRecover, + frame_evm::precompiles::Sha256, + frame_evm::precompiles::Ripemd160, + frame_evm::precompiles::Identity, + ); type ChainId = ChainId; } From c0908a0fb3c5e96c8e849ae246cea5cf4c71d1d2 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Sun, 27 Sep 2020 22:34:21 +0200 Subject: [PATCH 07/12] fix block parent hash (#135) --- frame/ethereum/src/lib.rs | 15 ++++++++++++--- ts-tests/tests/test-block.ts | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index f605575a13..7076714054 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -241,7 +241,7 @@ impl Module { let ommers = Vec::::new(); let header = ethereum::Header { - parent_hash: frame_system::Module::::parent_hash(), + parent_hash: Self::current_block_hash().unwrap_or_default(), ommers_hash: H256::from_slice( Keccak256::digest(&rlp::encode_list(&ommers)[..]).as_slice(), ), // TODO: check ommers hash. @@ -269,7 +269,7 @@ impl Module { mix_hash: H256::default(), nonce: H64::default(), }; - let hash = H256::from_slice(Keccak256::digest(&rlp::encode(&header)).as_slice()); + let hash = Self::ethereum_block_hash(&header); let block = ethereum::Block { header, @@ -313,11 +313,16 @@ impl Module { CurrentTransactionStatuses::get() } - /// Get block by number. + /// Get current block. pub fn current_block() -> Option { CurrentBlock::get() } + /// Get current block hash + pub fn current_block_hash() -> Option { + Self::current_block().map(|block| Self::ethereum_block_hash(&block.header)) + } + /// Get receipts by number. pub fn current_receipts() -> Option> { CurrentReceipts::get() @@ -430,4 +435,8 @@ impl Module { ExitError::Other(_s) => return Error::::ExitErrorOther, } } + + fn ethereum_block_hash(header: ðereum::Header) -> H256 { + H256::from_slice(Keccak256::digest(&rlp::encode(header)).as_slice()) + } } diff --git a/ts-tests/tests/test-block.ts b/ts-tests/tests/test-block.ts index e92b722f57..4251122ab8 100644 --- a/ts-tests/tests/test-block.ts +++ b/ts-tests/tests/test-block.ts @@ -117,7 +117,7 @@ describeWithFrontier("Frontier RPC (Block)", `simple-specs.json`, (context) => { expect(block).not.null; }); - it.skip("should include previous block hash as parent", async function () { + it("should include previous block hash as parent", async function () { this.timeout(15000); await createAndFinalizeBlock(context.web3); const block = await context.web3.eth.getBlock("latest"); From 98f9ce8b90ceefb5b95303d71b739ff57f94a8e2 Mon Sep 17 00:00:00 2001 From: Jake Naviasky Date: Sun, 27 Sep 2020 16:36:27 -0400 Subject: [PATCH 08/12] Add used_gas to receipts. (#139) * Add gas_used to receipts. * Add gas_used test. --- frame/ethereum/src/lib.rs | 20 ++++++++++---------- frame/ethereum/src/tests.rs | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index 7076714054..91044a6575 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -261,7 +261,7 @@ impl Module { ) ), gas_limit: U256::zero(), // TODO: set this using Ethereum's gas limit change algorithm. - gas_used: U256::zero(), // TODO: get this from receipts. + gas_used: receipts.clone().into_iter().fold(U256::zero(), |acc, r| acc + r.used_gas), timestamp: UniqueSaturatedInto::::unique_saturated_into( pallet_timestamp::Module::::get() ), @@ -335,9 +335,9 @@ impl Module { ); let transaction_index = Pending::get().len() as u32; - let status = match transaction.action { + let (status, gas_used) = match transaction.action { ethereum::TransactionAction::Call(target) => { - Self::handle_exec( + let (_, _, gas_used) = Self::handle_exec( pallet_evm::Module::::execute_call( source, target, @@ -350,7 +350,7 @@ impl Module { )? )?; - TransactionStatus { + (TransactionStatus { transaction_hash, transaction_index, from: source, @@ -358,10 +358,10 @@ impl Module { contract_address: None, logs: Vec::new(), // TODO: feed in logs. logs_bloom: Bloom::default(), // TODO: feed in bloom. - } + }, gas_used) }, ethereum::TransactionAction::Create => { - let contract_address = Self::handle_exec( + let (_, contract_address, gas_used) = Self::handle_exec( pallet_evm::Module::::execute_create( source, transaction.input.clone(), @@ -371,9 +371,9 @@ impl Module { Some(transaction.nonce), true, )? - )?.1; + )?; - TransactionStatus { + (TransactionStatus { transaction_hash, transaction_index, from: source, @@ -381,13 +381,13 @@ impl Module { contract_address: Some(contract_address), logs: Vec::new(), // TODO: feed in logs. logs_bloom: Bloom::default(), // TODO: feed in bloom. - } + }, gas_used) }, }; let receipt = ethereum::Receipt { state_root: H256::default(), // TODO: should be okay / error status. - used_gas: U256::default(), // TODO: set this. + used_gas: gas_used, logs_bloom: Bloom::default(), // TODO: set this. logs: Vec::new(), // TODO: set this. }; diff --git a/frame/ethereum/src/tests.rs b/frame/ethereum/src/tests.rs index 21266213f8..8a0a7ce31c 100644 --- a/frame/ethereum/src/tests.rs +++ b/frame/ethereum/src/tests.rs @@ -187,7 +187,6 @@ fn invalid_signature_should_be_ignored() { }); } - #[test] fn contract_should_be_created_at_given_address() { let (pairs, mut ext) = new_test_ext(1); @@ -203,3 +202,19 @@ fn contract_should_be_created_at_given_address() { assert_ne!(Evm::account_codes(erc20_address).len(), 0); }); } + +#[test] +fn transaction_should_generate_correct_gas_used() { + let (pairs, mut ext) = new_test_ext(1); + let alice = &pairs[0]; + + let expected_gas = U256::from(891328); + + ext.execute_with(|| { + assert_ok!(Ethereum::execute( + alice.address, + default_erc20_creation_transaction(alice), + )); + assert_eq!(Pending::get()[0].2.used_gas, expected_gas); + }); +} From 8f7f0f9e736a7660fab418fd459ffce72f3ea94e Mon Sep 17 00:00:00 2001 From: tgmichel Date: Mon, 28 Sep 2020 10:45:40 +0200 Subject: [PATCH 09/12] Frontier consensus one-to-many mapping (#133) * Frontier consensus one-to-many mapping * Cleanup * Checker fix --- consensus/src/aux_schema.rs | 15 +++++-- consensus/src/lib.rs | 4 +- rpc/Cargo.toml | 1 + rpc/src/lib.rs | 81 ++++++++++++++++++++++++------------- 4 files changed, 69 insertions(+), 32 deletions(-) diff --git a/consensus/src/aux_schema.rs b/consensus/src/aux_schema.rs index 354c40b8ca..7b4f7a3b6c 100644 --- a/consensus/src/aux_schema.rs +++ b/consensus/src/aux_schema.rs @@ -43,13 +43,14 @@ pub fn block_hash_key(ethereum_block_hash: H256) -> Vec { pub fn load_block_hash( backend: &B, hash: H256, -) -> ClientResult> { +) -> ClientResult>> { let key = block_hash_key(hash); load_decode(backend, &key) } /// Update Aux block hash. -pub fn write_block_hash( +pub fn write_block_hash( + client: &Backend, ethereum_hash: H256, block_hash: Hash, write_aux: F, @@ -57,7 +58,15 @@ pub fn write_block_hash( F: FnOnce(&[(&[u8], &[u8])]) -> R, { let key = block_hash_key(ethereum_hash); - write_aux(&[(&key, &block_hash.encode()[..])]) + + let mut data: Vec = match load_decode(client, &key) + { + Ok(Some(hashes)) => hashes, + _ => Vec::new(), + }; + data.push(block_hash); + + write_aux(&[(&key, &data.encode()[..])]) } /// Map an Ethereum transaction hash into its corresponding Ethereum block hash and index. diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs index cee102bd63..0ba3363200 100644 --- a/consensus/src/lib.rs +++ b/consensus/src/lib.rs @@ -126,6 +126,8 @@ impl BlockImport for FrontierBlockImport where ) } + let client = self.client.clone(); + if self.enabled { let log = find_frontier_log::(&block.header)?; let hash = block.post_hash(); @@ -134,7 +136,7 @@ impl BlockImport for FrontierBlockImport where ConsensusLog::EndBlock { block_hash, transaction_hashes, } => { - aux_schema::write_block_hash(block_hash, hash, insert_closure!()); + aux_schema::write_block_hash(client.as_ref(), block_hash, hash, insert_closure!()); for (index, transaction_hash) in transaction_hashes.into_iter().enumerate() { aux_schema::write_transaction_metadata( diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 1f29d55cdb..08de41d1ad 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -16,6 +16,7 @@ frontier-rpc-core = { path = "core" } frontier-rpc-primitives = { path = "primitives" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } +sp-blockchain = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-api = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-consensus = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-transaction-pool = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index c9e84a9738..dabc1e2c19 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -28,6 +28,7 @@ use sp_transaction_pool::TransactionPool; use sc_client_api::backend::{StorageProvider, Backend, StateBackend, AuxStore}; use sha3::{Keccak256, Digest}; use sp_runtime::traits::BlakeTwo256; +use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; use frontier_rpc_core::{EthApi as EthApiT, NetApi as NetApiT}; use frontier_rpc_core::types::{ BlockNumber, Bytes, CallRequest, Filter, Index, Log, Receipt, RichBlock, @@ -179,6 +180,7 @@ fn transaction_build( impl EthApi where C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, C::Api: EthereumRuntimeRPCApi, BE: Backend + 'static, BE::State: StateBackend, @@ -191,10 +193,7 @@ impl EthApi where fn native_block_id(&self, number: Option) -> Result>> { Ok(match number.unwrap_or(BlockNumber::Latest) { BlockNumber::Hash { hash, .. } => { - let hash = frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))?; - - hash.map(|h| BlockId::Hash(h)) + self.load_hash(hash).unwrap_or(None) }, BlockNumber::Num(number) => { Some(BlockId::Number(number.unique_saturated_into())) @@ -214,10 +213,36 @@ impl EthApi where } }) } + + // Asumes there is only one mapped canonical block in the AuxStore, otherwise something is wrong + fn load_hash(&self, hash: H256) -> Result>> { + let hashes = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) + .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + { + Some(hashes) => hashes, + None => return Ok(None), + }; + let out: Vec = hashes.into_iter() + .filter_map(|h| { + if let Ok(Some(_)) = self.client.header(BlockId::Hash(h)) { + Some(h) + } else { + None + } + }).collect(); + + if out.len() == 1 { + return Ok(Some( + BlockId::Hash(out[0]) + )); + } + Ok(None) + } } impl EthApiT for EthApi where C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, C::Api: EthereumRuntimeRPCApi, BE: Backend + 'static, BE::State: StateBackend, @@ -329,11 +354,11 @@ impl EthApiT for EthApi where } fn block_by_hash(&self, hash: H256, full: bool) -> Result> { - let id = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? { - Some(hash) => BlockId::Hash(hash), - None => return Ok(None), + Some(hash) => hash, + _ => return Ok(None), }; let block = self.client.runtime_api().current_block(&id) @@ -401,11 +426,11 @@ impl EthApiT for EthApi where } fn block_transaction_count_by_hash(&self, hash: H256) -> Result> { - let id = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? { - Some(hash) => BlockId::Hash(hash), - None => return Ok(None), + Some(hash) => hash, + _ => return Ok(None), }; let block = self.client.runtime_api() @@ -558,11 +583,11 @@ impl EthApiT for EthApi where None => return Ok(None), }; - let id = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? { - Some(hash) => BlockId::Hash(hash), - None => return Ok(None), + Some(hash) => hash, + _ => return Ok(None), }; let block = self.client.runtime_api().current_block(&id) @@ -587,11 +612,11 @@ impl EthApiT for EthApi where hash: H256, index: Index, ) -> Result> { - let id = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? { - Some(hash) => BlockId::Hash(hash), - None => return Ok(None), + Some(hash) => hash, + _ => return Ok(None), }; let index = index.value(); @@ -649,11 +674,11 @@ impl EthApiT for EthApi where None => return Ok(None), }; - let id = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? { - Some(hash) => BlockId::Hash(hash), - None => return Ok(None), + Some(hash) => hash, + _ => return Ok(None), }; let block = self.client.runtime_api().current_block(&id) @@ -739,11 +764,11 @@ impl EthApiT for EthApi where let mut ret = Vec::new(); if let Some(hash) = filter.block_hash { - let id = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? { - Some(hash) => BlockId::Hash(hash), - None => return Ok(ret), + Some(hash) => hash, + _ => return Ok(Vec::new()), }; let block = self.client.runtime_api() From c28889948362bf7b2ece8e9cf65a60415baa47d4 Mon Sep 17 00:00:00 2001 From: tgmichel Date: Mon, 28 Sep 2020 12:51:06 +0200 Subject: [PATCH 10/12] eth_pubsub support (#103) * Pubsub service setup * Add LatestHeader StorageValue, change Module name * Implement Kind::NewHeads for eth_subscribe * Styling fix * Add .cargo-remote.toml to .gitignore * Update Cargo.lock * pallet_ethereum LatestHeader to LatestBlock * Refactor to accommodate new Kinds * Implement Kind::Logs * Move Vec build to its own function * Added missing fields from Log response * Implement Kind::NewPendingTransactions * Implement eth_unsubscribe * Implement filtering for Kind::Logs * Small fixes * Add stream_build macro * Adapt to frontier consensus * Indentation cleanup * Formatting and cleanup * Remove unused imports * Remove Pending.take and add on_initialize * Fix Kind:NewPendingTransactions * Add NetworkService to pubsub rpc handler * Implement Kind::Syncing * Fix checker * pallet_ethereum handle Log response from evm execution * Runtime update substrate#12d0b7e * Return Vec in handle_exec * Fix checker * Runtime update substrate#93b2c36 * Bump jsonrpc-ore and jsonrpc-pubsub version * Update Cargo.lock * Update pallet-ethereum mock * Add missing const * Move internal error handler to crate root * Update pubsub to one-to-many * Skip previous block hash as parent test --- .gitignore | 1 + Cargo.lock | 868 ++++++++++++++++---------------- frame/ethereum/src/lib.rs | 44 +- frame/ethereum/src/mock.rs | 4 + rpc/Cargo.toml | 8 +- rpc/core/Cargo.toml | 4 +- rpc/core/src/eth_pubsub.rs | 2 + rpc/core/src/lib.rs | 2 +- rpc/core/src/types/mod.rs | 2 +- rpc/src/eth.rs | 931 +++++++++++++++++++++++++++++++++++ rpc/src/eth_pubsub.rs | 566 +++++++++++++++++++++ rpc/src/lib.rs | 921 +--------------------------------- template/node/Cargo.toml | 3 +- template/node/src/rpc.rs | 29 +- template/node/src/service.rs | 8 +- template/runtime/src/lib.rs | 10 +- ts-tests/tests/test-block.ts | 2 +- 17 files changed, 2025 insertions(+), 1380 deletions(-) create mode 100644 rpc/src/eth.rs create mode 100644 rpc/src/eth_pubsub.rs diff --git a/.gitignore b/.gitignore index 026a43a843..59aa2a2a24 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ node/runtime/wasm/target/ polkadot.* .DS_Store .idea/ +.cargo-remote.toml # Added by cargo /target diff --git a/Cargo.lock b/Cargo.lock index d4255584f0..40ad2af830 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,23 +40,11 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7001367fde4c768a19d1029f0a8be5abd9308e1119846d5bd9ad26297b8faf5" dependencies = [ - "aes-soft 0.4.0", - "aesni 0.7.0", + "aes-soft", + "aesni", "block-cipher", ] -[[package]] -name = "aes-ctr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" -dependencies = [ - "aes-soft 0.3.3", - "aesni 0.6.0", - "ctr", - "stream-cipher 0.3.2", -] - [[package]] name = "aes-gcm" version = "0.6.0" @@ -70,17 +58,6 @@ dependencies = [ "subtle 2.3.0", ] -[[package]] -name = "aes-soft" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" -dependencies = [ - "block-cipher-trait", - "byteorder 1.3.4", - "opaque-debug 0.2.3", -] - [[package]] name = "aes-soft" version = "0.4.0" @@ -92,17 +69,6 @@ dependencies = [ "opaque-debug 0.2.3", ] -[[package]] -name = "aesni" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -dependencies = [ - "block-cipher-trait", - "opaque-debug 0.2.3", - "stream-cipher 0.3.2", -] - [[package]] name = "aesni" version = "0.7.0" @@ -246,35 +212,47 @@ dependencies = [ [[package]] name = "async-executor" -version = "0.1.2" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d373d78ded7d0b3fa8039375718cde0aace493f2e34fb60f51cbf567562ca801" +dependencies = [ + "async-task 4.0.1", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell 1.4.1", + "vec-arena", +] + +[[package]] +name = "async-global-executor" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f47c78ea98277cb1f5e6f60ba4fc762f5eafe9f6511bc2f7dfd8b75c225650" +checksum = "ffd4f132a18f3fe7329c7b907047684f1b06174a900c559b661b2da8bb9cad5f" dependencies = [ + "async-executor", "async-io", "futures-lite", - "multitask", - "parking 1.0.6", - "scoped-tls", - "waker-fn", + "num_cpus", + "once_cell 1.4.1", ] [[package]] name = "async-io" -version = "0.1.11" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae22a338d28c75b53702b66f77979062cb29675db376d99e451af4fa79dedb3" +checksum = "64c629684e697f58c0e99e5e2d84a840e3b336afbcfdbac7b44c3b1e222c2fd8" dependencies = [ - "cfg-if", "concurrent-queue", + "fastrand", "futures-lite", - "libc", + "log", + "nb-connect", "once_cell 1.4.1", - "parking 2.0.0", + "parking", "polling", - "socket2", "vec-arena", - "wepoll-sys-stjepang", - "winapi 0.3.9", + "waker-fn", ] [[package]] @@ -288,21 +266,21 @@ dependencies = [ [[package]] name = "async-std" -version = "1.6.3" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c8da367da62b8ff2313c406c9ac091c1b31d67a165becdd2de380d846260f7" +checksum = "3c92085acfce8b32e5b261d0b59b8f3309aee69fea421ea3f271f8b93225754f" dependencies = [ - "async-executor", + "async-global-executor", "async-io", "async-mutex", - "async-task", + "async-task 3.0.0", "blocking", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", "futures-lite", - "futures-timer 3.0.2", + "gloo-timers", "kv-log-macro", "log", "memchr", @@ -320,6 +298,12 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3" +[[package]] +name = "async-task" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6725e96011a83fae25074a8734932e8d67763522839be7473dcfe8a0d6a378b1" + [[package]] name = "async-tls" version = "0.8.0" @@ -547,15 +531,6 @@ dependencies = [ "generic-array 0.14.4", ] -[[package]] -name = "block-cipher-trait" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" -dependencies = [ - "generic-array 0.12.3", -] - [[package]] name = "block-padding" version = "0.1.5" @@ -573,12 +548,13 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "0.5.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5800d29218fea137b0880387e5948694a23c93fcdde157006966693a865c7c" +checksum = "2640778f8053e72c11f621b0a5175a0560a269282aa98ed85107773ab8e2a556" dependencies = [ "async-channel", "atomic-waker", + "fastrand", "futures-lite", "once_cell 1.4.1", "waker-fn", @@ -660,9 +636,9 @@ checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" [[package]] name = "cc" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381" +checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c" dependencies = [ "jobserver", ] @@ -919,16 +895,6 @@ dependencies = [ "sct", ] -[[package]] -name = "ctr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" -dependencies = [ - "block-cipher-trait", - "stream-cipher 0.3.2", -] - [[package]] name = "cuckoofilter" version = "0.3.2" @@ -973,9 +939,9 @@ checksum = "d4d0e2d24e5ee3b23a01de38eefdcd978907890701f08ffffd4cb457ca4ee8d6" [[package]] name = "derive_more" -version = "0.99.9" +version = "0.99.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" +checksum = "1dcfabdab475c16a93d669dddfc393027803e347d09663f524447f642fbb84ba" dependencies = [ "proc-macro2", "quote", @@ -1060,9 +1026,9 @@ checksum = "4c53dc3a653e0f64081026e4bf048d48fec9fce90c66e8326ca7292df0ff2d82" [[package]] name = "ed25519" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf038a7b6fd7ef78ad3348b63f3a17550877b0e28f8d68bcc94894d1412158bc" +checksum = "07dfc993ea376e864fe29a4099a61ca0bb994c6d7745a61bf60ddb3d64e05237" dependencies = [ "signature", ] @@ -1083,9 +1049,9 @@ dependencies = [ [[package]] name = "either" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" @@ -1316,7 +1282,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", ] @@ -1324,7 +1290,7 @@ dependencies = [ [[package]] name = "frame-benchmarking" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -1342,12 +1308,13 @@ dependencies = [ [[package]] name = "frame-executive" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "serde", + "sp-core", "sp-io", "sp-runtime", "sp-std", @@ -1357,7 +1324,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "11.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "serde", @@ -1368,7 +1335,7 @@ dependencies = [ [[package]] name = "frame-support" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "bitmask", "frame-metadata", @@ -1393,7 +1360,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support-procedural-tools", "proc-macro2", @@ -1404,7 +1371,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1416,7 +1383,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "proc-macro2", "quote", @@ -1426,7 +1393,7 @@ dependencies = [ [[package]] name = "frame-system" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -1442,7 +1409,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-api", @@ -1490,16 +1457,21 @@ dependencies = [ "frontier-rpc-core", "frontier-rpc-primitives", "futures 0.3.5", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", + "jsonrpc-core 15.0.0", + "jsonrpc-core-client 14.2.0", + "jsonrpc-derive 14.2.2", + "jsonrpc-pubsub 15.0.0", + "log", "pallet-ethereum 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec", "rlp", "sc-client-api", + "sc-network", + "sc-rpc", "sc-service", "sha3 0.8.2", "sp-api", + "sp-blockchain", "sp-consensus", "sp-io", "sp-runtime", @@ -1512,10 +1484,10 @@ name = "frontier-rpc-core" version = "0.1.0" dependencies = [ "ethereum-types", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "jsonrpc-pubsub", + "jsonrpc-core 15.0.0", + "jsonrpc-core-client 14.2.0", + "jsonrpc-derive 14.2.2", + "jsonrpc-pubsub 15.0.0", "rustc-hex", "serde", "serde_json", @@ -1544,7 +1516,8 @@ dependencies = [ "frontier-rpc-primitives", "frontier-template-runtime", "futures 0.3.5", - "jsonrpc-core", + "jsonrpc-core 15.0.0", + "jsonrpc-pubsub 15.0.0", "log", "pallet-ethereum 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-evm", @@ -1761,15 +1734,15 @@ checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" [[package]] name = "futures-lite" -version = "0.1.11" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97999970129b808f0ccba93211201d431fcc12d7e1ffae03a61b5cedd1a7ced2" +checksum = "5b77e08e656f472d8ea84c472fa8b0a7a917883048e1cf2d4e34a323cd0aaf63" dependencies = [ "fastrand", "futures-core", "futures-io", "memchr", - "parking 2.0.0", + "parking", "pin-project-lite", "waker-fn", ] @@ -1812,10 +1785,6 @@ name = "futures-timer" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" -dependencies = [ - "gloo-timers", - "send_wrapper", -] [[package]] name = "futures-util" @@ -2162,6 +2131,12 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" +[[package]] +name = "httpdate" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" + [[package]] name = "humantime" version = "1.3.0" @@ -2203,9 +2178,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.7" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb" +checksum = "2f3afcfae8af5ad0576a31e768415edb627824129e8e5a29b8bfccb2f234e835" dependencies = [ "bytes 0.5.6", "futures-channel", @@ -2215,10 +2190,10 @@ dependencies = [ "http 0.2.1", "http-body 0.3.1", "httparse", + "httpdate", "itoa", "pin-project", "socket2", - "time", "tokio 0.2.22", "tower-service", "tracing", @@ -2234,7 +2209,7 @@ dependencies = [ "bytes 0.5.6", "ct-logs", "futures-util", - "hyper 0.13.7", + "hyper 0.13.8", "log", "rustls", "rustls-native-certs", @@ -2315,9 +2290,12 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485" +checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66" +dependencies = [ + "cfg-if", +] [[package]] name = "integer-sqrt" @@ -2368,15 +2346,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "0.4.6" @@ -2409,8 +2378,24 @@ checksum = "2773fa94a2a1fd51efb89a8f45b8861023dbb415d18d3c9235ae9388d780f9ec" dependencies = [ "failure", "futures 0.1.29", - "jsonrpc-core", - "jsonrpc-pubsub", + "jsonrpc-core 14.2.0", + "jsonrpc-pubsub 14.2.0", + "log", + "serde", + "serde_json", + "url 1.7.2", +] + +[[package]] +name = "jsonrpc-client-transports" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f7b1cdf66312002e15682a24430728bd13036c641163c016bc53fb686a7c2d" +dependencies = [ + "failure", + "futures 0.1.29", + "jsonrpc-core 15.0.0", + "jsonrpc-pubsub 15.0.0", "log", "serde", "serde_json", @@ -2430,13 +2415,35 @@ dependencies = [ "serde_json", ] +[[package]] +name = "jsonrpc-core" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b12567a31d48588a65b6cf870081e6ba1d7b2ae353977cb9820d512e69c70" +dependencies = [ + "futures 0.1.29", + "log", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "jsonrpc-core-client" version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34221123bc79b66279a3fde2d3363553835b43092d629b34f2e760c44dc94713" dependencies = [ - "jsonrpc-client-transports", + "jsonrpc-client-transports 14.2.1", +] + +[[package]] +name = "jsonrpc-core-client" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d175ca0cf77439b5495612bf216c650807d252d665b4b70ab2eebd895a88fac1" +dependencies = [ + "jsonrpc-client-transports 15.0.0", ] [[package]] @@ -2451,14 +2458,26 @@ dependencies = [ "syn", ] +[[package]] +name = "jsonrpc-derive" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2cc6ea7f785232d9ca8786a44e9fa698f92149dcdc1acc4aa1fc69c4993d79e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "jsonrpc-http-server" -version = "14.2.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da906d682799df05754480dac1b9e70ec92e12c19ebafd2662a5ea1c9fd6522" +checksum = "9996b26c0c7a59626d0ed6c5ec8bf06218e62ce1474bd2849f9b9fd38a0158c0" dependencies = [ "hyper 0.12.35", - "jsonrpc-core", + "jsonrpc-core 15.0.0", "jsonrpc-server-utils", "log", "net2", @@ -2468,11 +2487,11 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" -version = "14.2.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dedccd693325d833963b549e959137f30a7a0ea650cde92feda81dc0c1393cb5" +checksum = "b8e8f2278fb2b277175b6e21b23e7ecf30e78daff5ee301d0a2a411d9a821a0a" dependencies = [ - "jsonrpc-core", + "jsonrpc-core 15.0.0", "jsonrpc-server-utils", "log", "parity-tokio-ipc", @@ -2486,7 +2505,20 @@ version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d44f5602a11d657946aac09357956d2841299ed422035edf140c552cb057986" dependencies = [ - "jsonrpc-core", + "jsonrpc-core 14.2.0", + "log", + "parking_lot 0.10.2", + "rand 0.7.3", + "serde", +] + +[[package]] +name = "jsonrpc-pubsub" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f389c5cd1f3db258a99296892c21047e21ae73ff4c0e2d39650ea86fe994b4c7" +dependencies = [ + "jsonrpc-core 15.0.0", "log", "parking_lot 0.10.2", "rand 0.7.3", @@ -2495,13 +2527,13 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "14.2.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56cbfb462e7f902e21121d9f0d1c2b77b2c5b642e1a4e8f4ebfa2e15b94402bb" +checksum = "c623e1895d0d9110cb0ea7736cfff13191ff52335ad33b21bd5c775ea98b27af" dependencies = [ "bytes 0.4.12", "globset", - "jsonrpc-core", + "jsonrpc-core 15.0.0", "lazy_static", "log", "tokio 0.1.22", @@ -2511,16 +2543,16 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.2.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903d3109fe7c4acb932b567e1e607e0f524ed04741b09fb0e61841bc40a022fc" +checksum = "436a92034d0137ab3e3c64a7a6350b428f31cb4d7d1a89f284bcdbcd98a7bc56" dependencies = [ - "jsonrpc-core", + "jsonrpc-core 15.0.0", "jsonrpc-server-utils", "log", + "parity-ws", "parking_lot 0.10.2", "slab", - "ws", ] [[package]] @@ -2623,9 +2655,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.24.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c101edbb9c06955fd4085b77d2abc31cf3650134d77068b35c44967756ada8" +checksum = "571f5a4604c1a40d75651da141dfde29ad15329f537a779528803297d2220274" dependencies = [ "atomic", "bytes 0.5.6", @@ -2646,7 +2678,6 @@ dependencies = [ "libp2p-plaintext", "libp2p-pnet", "libp2p-request-response", - "libp2p-secio", "libp2p-swarm", "libp2p-tcp", "libp2p-uds", @@ -2663,9 +2694,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.21.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cea54ea4a846a7c47e4347db0fc7a4129dcb0fb57f07f57e473820edbfcbde" +checksum = "52f13ba8c7df0768af2eb391696d562c7de88cc3a35122531aaa6a7d77754d25" dependencies = [ "asn1_der", "bs58", @@ -2707,9 +2738,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6174d6addc9cc5fd84af7099480774035dd1a7cdf48dd31b23dea45cf57638" +checksum = "74029ae187f35f4b8ddf26b9779a68b340045d708528a103917cdca49a296db5" dependencies = [ "flate2", "futures 0.3.5", @@ -2718,9 +2749,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce8769cfe677a567d2677dc02a9e5be27a24acf1ff78a59cef425caae009a6a" +checksum = "7cf319822e08dd65c8e060d2354e9f952895bbc433f5706c75ed010c152aee5e" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -2729,9 +2760,9 @@ dependencies = [ [[package]] name = "libp2p-floodsub" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f2342965ac7ea4b85f4df5288089796421f9297ba4020dc9692f4ef728590dc" +checksum = "d8a9acb43a3e4a4e413e0c4abe0fa49308df7c6335c88534757b647199cb8a51" dependencies = [ "cuckoofilter", "fnv", @@ -2746,9 +2777,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0828b4f0c76c2edc68da574e391ce981bac5316d65785cddfe8c273d4c9bd4bb" +checksum = "ab20fcb60edebe3173bbb708c6ac3444afdf1e3152dc2866b10c4f5497f17467" dependencies = [ "base64 0.11.0", "byteorder 1.3.4", @@ -2772,9 +2803,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41efcb5b521b65d2c45432a244ce6427cdd3649228cd192f397d1fa67682aef2" +checksum = "56396ee63aa9164eacf40c2c5d2bda8c4133c2f57e1b0425d51d3a4e362583b1" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -2788,9 +2819,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.22.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca9b4ccc868863317af3f65eb241811ceadd971d133183040140f5496037e0ae" +checksum = "cc7fa9047f8b8f544278a35c2d9d45d3b2c1785f2d86d4e1629d6edf97be3955" dependencies = [ "arrayvec 0.5.1", "bytes 0.5.6", @@ -2815,9 +2846,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fe5614c2c5af74ef5870aad0fce73c9e4707716c4ee7cdf06cf9a0376d3815" +checksum = "3173b5a6b2f690c29ae07798d85b9441a131ac76ddae9015ef22905b623d0c69" dependencies = [ "async-std", "data-encoding", @@ -2837,9 +2868,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9e79541e71590846f773efce1b6d0538804992ee54ff2f407e05d63a9ddc23" +checksum = "8a73a799cc8410b36e40b8f4c4b6babbcb9efd3727111bf517876e4acfa612d3" dependencies = [ "bytes 0.5.6", "fnv", @@ -2853,9 +2884,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beba6459d06153f5f8e23da3df1d2183798b1f457c7c9468ff99760bcbcc60b" +checksum = "6ef6c490042f549fb1025f2892dfe6083d97a77558f450c1feebe748ca9eb15a" dependencies = [ "bytes 0.5.6", "curve25519-dalek 2.1.0", @@ -2875,9 +2906,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670261ef938567b614746b078e049b03b55617538a8d415071c518f97532d043" +checksum = "ad063c21dfcea4518ac9e8bd4119d33a5b26c41e674f602f41f05617a368a5c8" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -2890,9 +2921,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a61dfd53d1264ddff1206e4827193efaa72bab27782dfcd63c0dec120a1875" +checksum = "903a12e99c72dbebefea258de887982adeacc7025baa1ceb10b7fa9928f54791" dependencies = [ "bytes 0.5.6", "futures 0.3.5", @@ -2922,57 +2953,31 @@ dependencies = [ [[package]] name = "libp2p-request-response" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af0de0e56a11d46c5191a61019733b5618dc955c0a36f82866bb6d5d81a7f8f" +checksum = "9c0c9e8a4cd69d97e9646c54313d007512f411aba8c5226cfcda16df6a6e84a3" dependencies = [ "async-trait", + "bytes 0.5.6", "futures 0.3.5", "libp2p-core", "libp2p-swarm", "log", "lru 0.6.0", + "minicbor", "rand 0.7.3", "smallvec 1.4.2", + "unsigned-varint 0.5.1", "wasm-timer", ] -[[package]] -name = "libp2p-secio" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a04b320cc0394554e8d0adca21f4efd9f8c2da4930211d92e411a19a4dfd769e" -dependencies = [ - "aes-ctr", - "ctr", - "futures 0.3.5", - "hmac", - "js-sys", - "lazy_static", - "libp2p-core", - "log", - "parity-send-wrapper", - "pin-project", - "prost", - "prost-build", - "quicksink", - "rand 0.7.3", - "ring", - "rw-stream-sink", - "sha2 0.8.2", - "static_assertions", - "twofish", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "libp2p-swarm" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e4a7e64156e9d1a2daae36b5d791f057b9c53c9364a8e75f7f9848b54f9d68" +checksum = "7193e444210132237b81b755ec7fe53f1c4bd2f53cf719729b94c0c72eb6eaa1" dependencies = [ + "either", "futures 0.3.5", "libp2p-core", "log", @@ -2984,9 +2989,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f65400ccfbbf9a356733bceca6c519c9db0deb5fbcc0b81f89837c4cd53997" +checksum = "44f42ec130d7a37a7e47bf4398026b7ad9185c08ed26972e2720f8b94112796f" dependencies = [ "async-std", "futures 0.3.5", @@ -3000,9 +3005,9 @@ dependencies = [ [[package]] name = "libp2p-uds" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95bc8b0ca1dda4cccb1bb156d47a32e45cfa447ef18f737209f014a63f94a4a2" +checksum = "dea7acb0a034f70d7db94c300eba3f65c0f6298820105624088a9609c9974d77" dependencies = [ "async-std", "futures 0.3.5", @@ -3012,9 +3017,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2f7b06d80d036ac5763a811185b7fe6951ad71c00544b17cc378a9069bb7c2" +checksum = "34c1faac6f92c21fbe155417957863ea822fba9e9fd5eb24c0912336a100e63f" dependencies = [ "futures 0.3.5", "js-sys", @@ -3026,9 +3031,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b350db65cf0a7c83a539a596ea261caae1552c0df2245df0f916ed2fd04572" +checksum = "d650534ebd99f48f6fa292ed5db10d30df2444943afde4407ceeddab8e513fca" dependencies = [ "async-tls", "either", @@ -3046,13 +3051,13 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.21.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3969ead4ce530efb6f304623924245caf410f3b0b0139bd7007f205933788aa" +checksum = "781d9b9f043dcdabc40640807125368596b849fd4d96cdca2dcf052fdf6f33fd" dependencies = [ "futures 0.3.5", "libp2p-core", - "parking_lot 0.10.2", + "parking_lot 0.11.0", "thiserror", "yamux", ] @@ -3230,9 +3235,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" dependencies = [ "autocfg 1.0.1", ] @@ -3267,12 +3272,33 @@ dependencies = [ ] [[package]] -name = "miniz_oxide" +name = "minicbor" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc03ad6f8f548db7194a5ff5a6f96342ecae4e3ef67d2bf18bacc0e245cd041" +dependencies = [ + "minicbor-derive", +] + +[[package]] +name = "minicbor-derive" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722" +checksum = "c214bf3d90099b52f3e4b328ae0fe34837fd0fab683ad1e10fceb4629106df48" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9" dependencies = [ "adler", + "autocfg 1.0.1", ] [[package]] @@ -3386,17 +3412,6 @@ dependencies = [ "unsigned-varint 0.4.0", ] -[[package]] -name = "multitask" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c09c35271e7dcdb5f709779111f2c8e8ab8e06c1b587c1c6a9e179d865aaa5b4" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", -] - [[package]] name = "nalgebra" version = "0.18.1" @@ -3423,6 +3438,16 @@ dependencies = [ "rand 0.3.23", ] +[[package]] +name = "nb-connect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847c76b390f44529c2071ef06d0b52fbb4bdb04cc8987a5cfa63954c000abca" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "net2" version = "0.2.35" @@ -3586,7 +3611,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -3605,7 +3630,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -3620,7 +3645,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-benchmarking", "frame-support", @@ -3666,7 +3691,7 @@ checksum = "bd4556fb64842e71bb6e2f98b7541c0d310069eb607d432c6ac9bdaecbfd3118" [[package]] name = "pallet-evm" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "evm", "frame-support", @@ -3689,7 +3714,7 @@ dependencies = [ [[package]] name = "pallet-finality-tracker" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -3705,7 +3730,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-benchmarking", "frame-support", @@ -3727,7 +3752,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -3740,7 +3765,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -3760,7 +3785,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -3774,7 +3799,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-benchmarking", "frame-support", @@ -3791,7 +3816,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "frame-system", @@ -3808,11 +3833,11 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", + "jsonrpc-core 15.0.0", + "jsonrpc-core-client 15.0.0", + "jsonrpc-derive 15.0.0", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "serde", @@ -3826,7 +3851,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-support", "parity-scale-codec", @@ -3952,10 +3977,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" [[package]] -name = "parking" -version = "1.0.6" +name = "parity-ws" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c" +checksum = "9e02a625dd75084c2a7024f07c575b61b782f729d18702dabb3cdbf31911dc61" +dependencies = [ + "byteorder 1.3.4", + "bytes 0.4.12", + "httparse", + "log", + "mio", + "mio-extras", + "rand 0.7.3", + "sha-1 0.8.2", + "slab", + "url 2.1.1", +] [[package]] name = "parking" @@ -4172,9 +4209,9 @@ checksum = "feb3b2b1033b8a60b4da6ee470325f887758c95d5320f52f9ce0df055a55940e" [[package]] name = "polling" -version = "0.1.9" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fffa183f6bd5f1a8a3e1f60ce2f8d5621e350eed84a62d6daaa5b9d1aaf6fbd" +checksum = "e0720e0b9ea9d52451cf29d3413ba8a9303f8815d9d9653ef70e03ff73e65566" dependencies = [ "cfg-if", "libc", @@ -4307,7 +4344,7 @@ checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" dependencies = [ "bytes 0.5.6", "heck", - "itertools 0.8.2", + "itertools", "log", "multimap", "petgraph", @@ -4324,7 +4361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ "anyhow", - "itertools 0.8.2", + "itertools", "proc-macro2", "quote", "syn", @@ -4585,9 +4622,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91739a34c4355b5434ce54c9086c5895604a9c278586d1f1aa95e04f66b525a0" +checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -4679,27 +4716,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "rental" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8545debe98b2b139fb04cad8618b530e9b07c152d99a5de83c860b877d67847f" -dependencies = [ - "rental-impl", - "stable_deref_trait", -] - -[[package]] -name = "rental-impl" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475e68978dc5b743f2f40d8e0a8fdc83f1c5e78cbf4b8fa5e74e73beebc340de" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "retain_mut" version = "0.1.1" @@ -4885,7 +4901,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", @@ -4909,7 +4925,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -4926,7 +4942,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -4943,7 +4959,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4954,14 +4970,13 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "ansi_term 0.12.1", "atty", "bip39", "chrono", "derive_more", - "env_logger", "fdlimit", "futures 0.3.5", "hex", @@ -4996,12 +5011,15 @@ dependencies = [ "substrate-prometheus-endpoint", "time", "tokio 0.2.22", + "tracing", + "tracing-log", + "tracing-subscriber", ] [[package]] name = "sc-client-api" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "fnv", @@ -5037,7 +5055,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "blake2-rfc", "hash-db", @@ -5067,7 +5085,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "sc-client-api", "sp-blockchain", @@ -5078,7 +5096,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "futures 0.3.5", @@ -5109,7 +5127,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "fork-tree", @@ -5153,7 +5171,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "fork-tree", "parity-scale-codec", @@ -5166,14 +5184,14 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "assert_matches", "derive_more", "futures 0.3.5", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", + "jsonrpc-core 15.0.0", + "jsonrpc-core-client 15.0.0", + "jsonrpc-derive 15.0.0", "log", "parking_lot 0.10.2", "sc-client-api", @@ -5197,7 +5215,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", @@ -5220,7 +5238,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "log", "sc-client-api", @@ -5234,7 +5252,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "lazy_static", @@ -5261,7 +5279,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "log", @@ -5278,7 +5296,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "log", "parity-scale-codec", @@ -5293,7 +5311,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "finality-grandpa", @@ -5330,7 +5348,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "ansi_term 0.12.1", "futures 0.3.5", @@ -5348,7 +5366,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "hex", @@ -5364,7 +5382,7 @@ dependencies = [ [[package]] name = "sc-light" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "hash-db", "lazy_static", @@ -5383,7 +5401,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "async-std", "async-trait", @@ -5437,7 +5455,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", @@ -5452,13 +5470,13 @@ dependencies = [ [[package]] name = "sc-offchain" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "bytes 0.5.6", "fnv", "futures 0.3.5", "futures-timer 3.0.2", - "hyper 0.13.7", + "hyper 0.13.8", "hyper-rustls", "log", "num_cpus", @@ -5479,7 +5497,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "libp2p", @@ -5492,7 +5510,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -5501,12 +5519,12 @@ dependencies = [ [[package]] name = "sc-rpc" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "hash-db", - "jsonrpc-core", - "jsonrpc-pubsub", + "jsonrpc-core 15.0.0", + "jsonrpc-pubsub 15.0.0", "log", "parity-scale-codec", "parking_lot 0.10.2", @@ -5533,14 +5551,14 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "futures 0.3.5", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "jsonrpc-pubsub", + "jsonrpc-core 15.0.0", + "jsonrpc-core-client 15.0.0", + "jsonrpc-derive 15.0.0", + "jsonrpc-pubsub 15.0.0", "log", "parity-scale-codec", "parking_lot 0.10.2", @@ -5557,23 +5575,25 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ - "jsonrpc-core", + "futures 0.1.29", + "jsonrpc-core 15.0.0", "jsonrpc-http-server", "jsonrpc-ipc-server", - "jsonrpc-pubsub", + "jsonrpc-pubsub 15.0.0", "jsonrpc-ws-server", "log", "serde", "serde_json", "sp-runtime", + "substrate-prometheus-endpoint", ] [[package]] name = "sc-service" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "directories", @@ -5582,8 +5602,8 @@ dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", "hash-db", - "jsonrpc-core", - "jsonrpc-pubsub", + "jsonrpc-core 15.0.0", + "jsonrpc-pubsub 15.0.0", "lazy_static", "log", "parity-scale-codec", @@ -5621,6 +5641,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-state-machine", + "sp-tracing", "sp-transaction-pool", "sp-trie", "sp-utils", @@ -5634,7 +5655,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "log", "parity-scale-codec", @@ -5648,7 +5669,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "futures-timer 3.0.2", @@ -5669,7 +5690,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "erased-serde", "log", @@ -5681,13 +5702,14 @@ dependencies = [ "slog", "sp-tracing", "tracing", + "tracing-core", "tracing-subscriber", ] [[package]] name = "sc-transaction-graph" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "futures 0.3.5", @@ -5708,7 +5730,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "futures 0.3.5", @@ -5759,12 +5781,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - [[package]] name = "scopeguard" version = "0.3.3" @@ -5834,26 +5850,20 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - [[package]] name = "serde" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" dependencies = [ "proc-macro2", "quote", @@ -6091,7 +6101,7 @@ dependencies = [ [[package]] name = "sp-allocator" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "log", @@ -6103,7 +6113,7 @@ dependencies = [ [[package]] name = "sp-api" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "hash-db", "parity-scale-codec", @@ -6118,7 +6128,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "blake2-rfc", "proc-macro-crate", @@ -6130,7 +6140,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "serde", @@ -6142,7 +6152,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "integer-sqrt", "num-traits", @@ -6155,7 +6165,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -6166,7 +6176,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-api", @@ -6178,7 +6188,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "log", @@ -6195,7 +6205,7 @@ dependencies = [ [[package]] name = "sp-chain-spec" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "serde", "serde_json", @@ -6204,7 +6214,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "futures 0.3.5", @@ -6230,7 +6240,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-api", @@ -6244,7 +6254,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "merlin", "parity-scale-codec", @@ -6263,7 +6273,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -6272,7 +6282,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -6284,7 +6294,7 @@ dependencies = [ [[package]] name = "sp-core" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "base58", "blake2-rfc", @@ -6328,7 +6338,7 @@ dependencies = [ [[package]] name = "sp-database" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "kvdb", "parking_lot 0.10.2", @@ -6337,7 +6347,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "proc-macro2", "quote", @@ -6347,7 +6357,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "environmental", "parity-scale-codec", @@ -6358,7 +6368,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "finality-grandpa", "log", @@ -6374,7 +6384,7 @@ dependencies = [ [[package]] name = "sp-finality-tracker" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -6384,7 +6394,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "parity-scale-codec", @@ -6396,7 +6406,7 @@ dependencies = [ [[package]] name = "sp-io" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "hash-db", @@ -6412,12 +6422,14 @@ dependencies = [ "sp-tracing", "sp-trie", "sp-wasm-interface", + "tracing", + "tracing-core", ] [[package]] name = "sp-keyring" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "lazy_static", "sp-core", @@ -6428,7 +6440,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "sp-api", "sp-core", @@ -6438,7 +6450,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "backtrace", "log", @@ -6447,7 +6459,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "serde", "sp-core", @@ -6456,7 +6468,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "either", "hash256-std-hasher", @@ -6478,7 +6490,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "primitive-types", @@ -6494,7 +6506,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "Inflector", "proc-macro-crate", @@ -6506,7 +6518,7 @@ dependencies = [ [[package]] name = "sp-serializer" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "serde", "serde_json", @@ -6515,7 +6527,7 @@ dependencies = [ [[package]] name = "sp-session" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-api", @@ -6528,7 +6540,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -6538,10 +6550,9 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "hash-db", - "itertools 0.9.0", "log", "num-traits", "parity-scale-codec", @@ -6551,6 +6562,7 @@ dependencies = [ "sp-core", "sp-externalities", "sp-panic-handler", + "sp-std", "sp-trie", "trie-db", "trie-root", @@ -6559,12 +6571,12 @@ dependencies = [ [[package]] name = "sp-std" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" [[package]] name = "sp-storage" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "impl-serde", "parity-scale-codec", @@ -6577,7 +6589,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -6591,17 +6603,20 @@ dependencies = [ [[package]] name = "sp-tracing" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "log", - "rental", + "parity-scale-codec", + "sp-std", "tracing", + "tracing-core", + "tracing-subscriber", ] [[package]] name = "sp-transaction-pool" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "derive_more", "futures 0.3.5", @@ -6616,7 +6631,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "hash-db", "memory-db", @@ -6630,7 +6645,7 @@ dependencies = [ [[package]] name = "sp-utils" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.3.5", "futures-core", @@ -6642,7 +6657,7 @@ dependencies = [ [[package]] name = "sp-version" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "impl-serde", "parity-scale-codec", @@ -6654,7 +6669,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -6783,7 +6798,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "platforms", ] @@ -6791,13 +6806,13 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.5", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", + "jsonrpc-core 15.0.0", + "jsonrpc-core-client 15.0.0", + "jsonrpc-derive 15.0.0", "log", "parity-scale-codec", "sc-client-api", @@ -6814,12 +6829,12 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.8.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.7", + "hyper 0.13.8", "log", "prometheus", "tokio 0.2.22", @@ -6828,7 +6843,7 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.0-rc6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" dependencies = [ "futures 0.1.29", "futures 0.3.5", @@ -6854,7 +6869,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder-runner" version = "1.0.6" -source = "git+https://github.com/paritytech/substrate.git?branch=frontier#50c1820b856ae6d934b281da5f1eda3c6bdaba40" +source = "git+https://github.com/paritytech/substrate.git?branch=frontier#7314ddce65d6023ccb7ae18006a4ada792604bfd" [[package]] name = "subtle" @@ -6870,9 +6885,9 @@ checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" [[package]] name = "syn" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350" +checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" dependencies = [ "proc-macro2", "quote", @@ -7354,9 +7369,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" dependencies = [ "serde", "tracing-core", @@ -7364,9 +7379,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd165311cc4d7a555ad11cc77a37756df836182db0d81aac908c8184c584f40" +checksum = "82bb5079aa76438620837198db8a5c529fb9878c730bc2b28179b0241cf04c10" dependencies = [ "ansi_term 0.12.1", "chrono", @@ -7411,17 +7426,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" -[[package]] -name = "twofish" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" -dependencies = [ - "block-cipher-trait", - "byteorder 1.3.4", - "opaque-debug 0.2.3", -] - [[package]] name = "twox-hash" version = "1.5.0" @@ -7521,6 +7525,10 @@ name = "unsigned-varint" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35" +dependencies = [ + "futures-io", + "futures-util", +] [[package]] name = "untrusted" @@ -7558,9 +7566,9 @@ checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" [[package]] name = "vec-arena" -version = "0.5.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb18268690309760d59ee1a9b21132c126ba384f374c59a94db4bc03adeb561" +checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" [[package]] name = "vec_map" @@ -7763,9 +7771,9 @@ dependencies = [ [[package]] name = "wepoll-sys-stjepang" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694" +checksum = "1fdfbb03f290ca0b27922e8d48a0997b4ceea12df33269b9f75e713311eb178d" dependencies = [ "cc", ] @@ -7822,24 +7830,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "ws" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94" -dependencies = [ - "byteorder 1.3.4", - "bytes 0.4.12", - "httparse", - "log", - "mio", - "mio-extras", - "rand 0.7.3", - "sha-1 0.8.2", - "slab", - "url 2.1.1", -] - [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -7863,32 +7853,32 @@ dependencies = [ [[package]] name = "yamux" -version = "0.4.9" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053585b18bca1a3d00e4b5ef93e72d4f49a10005374c455db7177e27149c899d" +checksum = "9aeb8c4043cac71c3c299dff107171c220d179492350ea198e109a414981b83c" dependencies = [ "futures 0.3.5", "log", "nohash-hasher", - "parking_lot 0.10.2", + "parking_lot 0.11.0", "rand 0.7.3", "static_assertions", ] [[package]] name = "zeroize" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" +checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" +checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" dependencies = [ "proc-macro2", "quote", diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index 91044a6575..bf849ee612 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -61,7 +61,7 @@ pub trait Trait: frame_system::Trait + pallet_balances::Trait + palle } decl_storage! { - trait Store for Module as Example { + trait Store for Module as Ethereum { /// Current building block's transactions and receipts. Pending: Vec<(ethereum::Transaction, TransactionStatus, ethereum::Receipt)>; @@ -162,6 +162,11 @@ decl_module! { fn on_finalize(n: T::BlockNumber) { >::store_block(); } + + fn on_initialize(n: T::BlockNumber) -> frame_support::weights::Weight { + Pending::kill(); + 0 + } } } @@ -228,12 +233,10 @@ impl Module { } fn store_block() { - let pending = Pending::take(); - let mut transactions = Vec::new(); let mut statuses = Vec::new(); let mut receipts = Vec::new(); - for (transaction, status, receipt) in pending { + for (transaction, status, receipt) in Pending::get() { transactions.push(transaction); statuses.push(status); receipts.push(receipt); @@ -272,7 +275,7 @@ impl Module { let hash = Self::ethereum_block_hash(&header); let block = ethereum::Block { - header, + header: header.clone(), transactions: transactions.clone(), ommers, }; @@ -337,7 +340,7 @@ impl Module { let (status, gas_used) = match transaction.action { ethereum::TransactionAction::Call(target) => { - let (_, _, gas_used) = Self::handle_exec( + let (_, _, gas_used, logs) = Self::handle_exec( pallet_evm::Module::::execute_call( source, target, @@ -356,12 +359,21 @@ impl Module { from: source, to: Some(target), contract_address: None, - logs: Vec::new(), // TODO: feed in logs. + logs: { + logs.into_iter() + .map(|log| { + Log { + address: log.address, + topics: log.topics, + data: log.data + } + }).collect() + }, logs_bloom: Bloom::default(), // TODO: feed in bloom. }, gas_used) }, ethereum::TransactionAction::Create => { - let (_, contract_address, gas_used) = Self::handle_exec( + let (_, contract_address, gas_used, logs) = Self::handle_exec( pallet_evm::Module::::execute_create( source, transaction.input.clone(), @@ -379,7 +391,16 @@ impl Module { from: source, to: None, contract_address: Some(contract_address), - logs: Vec::new(), // TODO: feed in logs. + logs: { + logs.into_iter() + .map(|log| { + Log { + address: log.address, + topics: log.topics, + data: log.data + } + }).collect() + }, logs_bloom: Bloom::default(), // TODO: feed in bloom. }, gas_used) }, @@ -389,7 +410,7 @@ impl Module { state_root: H256::default(), // TODO: should be okay / error status. used_gas: gas_used, logs_bloom: Bloom::default(), // TODO: set this. - logs: Vec::new(), // TODO: set this. + logs: status.clone().logs, }; Pending::append((transaction, status, receipt)); @@ -397,7 +418,8 @@ impl Module { Ok(()) } - fn handle_exec(res: (ExitReason, R, U256)) -> Result<(ExitReason, R, U256), Error> { + fn handle_exec(res: (ExitReason, R, U256, Vec)) + -> Result<(ExitReason, R, U256, Vec), Error> { match res.0 { ExitReason::Succeed(_s) => Ok(res), ExitReason::Error(e) => Err(Self::parse_exit_error(e)), diff --git a/frame/ethereum/src/mock.rs b/frame/ethereum/src/mock.rs index e312201b39..bbd63ad52f 100644 --- a/frame/ethereum/src/mock.rs +++ b/frame/ethereum/src/mock.rs @@ -76,10 +76,14 @@ impl frame_system::Trait for Test { } parameter_types! { + // For weight estimation, we assume that the most locks on an individual account will be 50. + // This number may need to be adjusted in the future if this assumption no longer holds true. + pub const MaxLocks: u32 = 50; pub const ExistentialDeposit: u64 = 500; } impl pallet_balances::Trait for Test { + type MaxLocks = MaxLocks; type Balance = u64; type Event = (); type DustRemoval = (); diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 08de41d1ad..12a46df934 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -7,22 +7,26 @@ description = "Ethereum RPC (web3) compatibility layer for Substrate." license = "GPL-3.0" [dependencies] -jsonrpc-core = "14.0.3" +jsonrpc-core = "15.0.0" jsonrpc-derive = "14.0.3" jsonrpc-core-client = "14.0.3" +jsonrpc-pubsub = "15.0.0" +log = "0.4.8" ethereum-types = "0.9.0" frontier-consensus = { path = "../consensus" } frontier-rpc-core = { path = "core" } frontier-rpc-primitives = { path = "primitives" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } -sp-blockchain = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-api = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-consensus = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-transaction-pool = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-storage = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } +sp-blockchain = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sc-service = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sc-client-api = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } +sc-rpc = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } +sc-network = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } ethereum = { version = "0.3", features = ["codec"] } codec = { package = "parity-scale-codec", version = "1.0.0" } rlp = "0.4" diff --git a/rpc/core/Cargo.toml b/rpc/core/Cargo.toml index d78829e0e5..8c89b91c75 100644 --- a/rpc/core/Cargo.toml +++ b/rpc/core/Cargo.toml @@ -7,10 +7,10 @@ description = "RPC traits of Ethereum." license = "GPL-3.0" [dependencies] -jsonrpc-core = "14.0.3" +jsonrpc-core = "15.0.0" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -jsonrpc-pubsub = "14.0.5" +jsonrpc-pubsub = "15.0.0" rustc-hex = "2.1.0" ethereum-types = "0.9.0" serde = { version = "1.0", features = ["derive"] } diff --git a/rpc/core/src/eth_pubsub.rs b/rpc/core/src/eth_pubsub.rs index 13a02abf1c..99c6dc1ff9 100644 --- a/rpc/core/src/eth_pubsub.rs +++ b/rpc/core/src/eth_pubsub.rs @@ -22,6 +22,8 @@ use jsonrpc_pubsub::{typed, SubscriptionId}; use crate::types::pubsub; +pub use rpc_impl_EthPubSubApi::gen_server::EthPubSubApi as EthPubSubApiServer; + /// Eth PUB-SUB rpc interface. #[rpc(server)] pub trait EthPubSubApi { diff --git a/rpc/core/src/lib.rs b/rpc/core/src/lib.rs index 7d27c1213a..55d3f7c3e4 100644 --- a/rpc/core/src/lib.rs +++ b/rpc/core/src/lib.rs @@ -23,7 +23,7 @@ mod net; mod web3; pub use eth::{EthApi, EthApiServer, EthFilterApi}; -pub use eth_pubsub::EthPubSubApi; +pub use eth_pubsub::{EthPubSubApi, EthPubSubApiServer}; pub use eth_signing::EthSigningApi; pub use net::{NetApi, NetApiServer}; pub use web3::Web3Api; diff --git a/rpc/core/src/types/mod.rs b/rpc/core/src/types/mod.rs index a9ee007cc2..26bc3d39fb 100644 --- a/rpc/core/src/types/mod.rs +++ b/rpc/core/src/types/mod.rs @@ -38,7 +38,7 @@ pub use self::bytes::Bytes; pub use self::block::{RichBlock, Block, BlockTransactions, Header, RichHeader, Rich}; pub use self::block_number::BlockNumber; pub use self::call_request::CallRequest; -pub use self::filter::{Filter, FilterChanges, VariadicValue}; +pub use self::filter::{Filter, FilterChanges, VariadicValue, FilterAddress, Topic}; pub use self::index::Index; pub use self::log::Log; pub use self::receipt::Receipt; diff --git a/rpc/src/eth.rs b/rpc/src/eth.rs new file mode 100644 index 0000000000..3a53850fe8 --- /dev/null +++ b/rpc/src/eth.rs @@ -0,0 +1,931 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Frontier. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use std::{marker::PhantomData, sync::Arc}; +use std::collections::BTreeMap; +use ethereum::{Block as EthereumBlock, Transaction as EthereumTransaction}; +use ethereum_types::{H160, H256, H64, U256, U64, H512}; +use jsonrpc_core::{BoxFuture, Result, futures::future::{self, Future}}; +use futures::future::TryFutureExt; +use sp_runtime::traits::{Block as BlockT, Header as _, UniqueSaturatedInto, Zero, One, Saturating}; +use sp_runtime::transaction_validity::TransactionSource; +use sp_api::{ProvideRuntimeApi, BlockId}; +use sp_consensus::SelectChain; +use sp_transaction_pool::TransactionPool; +use sc_client_api::backend::{StorageProvider, Backend, StateBackend, AuxStore}; +use sha3::{Keccak256, Digest}; +use sp_runtime::traits::BlakeTwo256; +use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; +use frontier_rpc_core::{EthApi as EthApiT, NetApi as NetApiT}; +use frontier_rpc_core::types::{ + BlockNumber, Bytes, CallRequest, Filter, Index, Log, Receipt, RichBlock, + SyncStatus, SyncInfo, Transaction, Work, Rich, Block, BlockTransactions, VariadicValue +}; +use frontier_rpc_primitives::{EthereumRuntimeRPCApi, ConvertTransaction, TransactionStatus}; +use crate::internal_err; + +pub use frontier_rpc_core::{EthApiServer, NetApiServer}; + +pub struct EthApi { + pool: Arc

, + client: Arc, + select_chain: SC, + convert_transaction: CT, + is_authority: bool, + _marker: PhantomData<(B, BE)>, +} + +impl EthApi { + pub fn new( + client: Arc, + select_chain: SC, + pool: Arc

, + convert_transaction: CT, + is_authority: bool + ) -> Self { + Self { client, select_chain, pool, convert_transaction, is_authority, _marker: PhantomData } + } +} + +fn rich_block_build( + block: ethereum::Block, + statuses: Vec>, + hash: Option, + full_transactions: bool +) -> RichBlock { + Rich { + inner: Block { + hash: Some(hash.unwrap_or_else(|| { + H256::from_slice( + Keccak256::digest(&rlp::encode(&block.header)).as_slice() + ) + })), + parent_hash: block.header.parent_hash, + uncles_hash: H256::zero(), + author: block.header.beneficiary, + miner: block.header.beneficiary, + state_root: block.header.state_root, + transactions_root: block.header.transactions_root, + receipts_root: block.header.receipts_root, + number: Some(block.header.number), + gas_used: block.header.gas_used, + gas_limit: block.header.gas_limit, + extra_data: Bytes(block.header.extra_data.as_bytes().to_vec()), + logs_bloom: Some(block.header.logs_bloom), + timestamp: U256::from(block.header.timestamp / 1000), + difficulty: block.header.difficulty, + total_difficulty: None, + seal_fields: vec![ + Bytes(block.header.mix_hash.as_bytes().to_vec()), + Bytes(block.header.nonce.as_bytes().to_vec()) + ], + uncles: vec![], + transactions: { + if full_transactions { + BlockTransactions::Full( + block.transactions.iter().enumerate().map(|(index, transaction)|{ + transaction_build( + transaction.clone(), + block.clone(), + statuses[index].clone().unwrap_or_default() + ) + }).collect() + ) + } else { + BlockTransactions::Hashes( + block.transactions.iter().map(|transaction|{ + H256::from_slice( + Keccak256::digest(&rlp::encode(&transaction.clone())).as_slice() + ) + }).collect() + ) + } + }, + size: Some(U256::from(rlp::encode(&block).len() as u32)) + }, + extra_info: BTreeMap::new() + } +} + +fn transaction_build( + transaction: EthereumTransaction, + block: EthereumBlock, + status: TransactionStatus +) -> Transaction { + let mut sig = [0u8; 65]; + let mut msg = [0u8; 32]; + sig[0..32].copy_from_slice(&transaction.signature.r()[..]); + sig[32..64].copy_from_slice(&transaction.signature.s()[..]); + sig[64] = transaction.signature.standard_v(); + msg.copy_from_slice(&transaction.message_hash( + transaction.signature.chain_id().map(u64::from) + )[..]); + + let pubkey = match sp_io::crypto::secp256k1_ecdsa_recover(&sig, &msg) { + Ok(p) => Some(H512::from(p)), + Err(_e) => None, + }; + + Transaction { + hash: H256::from_slice( + Keccak256::digest(&rlp::encode(&transaction)).as_slice() + ), + nonce: transaction.nonce, + block_hash: Some(H256::from_slice( + Keccak256::digest(&rlp::encode(&block.header)).as_slice() + )), + block_number: Some(block.header.number), + transaction_index: Some(U256::from( + UniqueSaturatedInto::::unique_saturated_into( + status.transaction_index + ) + )), + from: status.from, + to: status.to, + value: transaction.value, + gas_price: transaction.gas_price, + gas: transaction.gas_limit, + input: Bytes(transaction.clone().input), + creates: status.contract_address, + raw: Bytes(rlp::encode(&transaction)), + public_key: pubkey, + chain_id: transaction.signature.chain_id().map(U64::from), + standard_v: U256::from(transaction.signature.standard_v()), + v: U256::from(transaction.signature.v()), + r: U256::from(transaction.signature.r().as_bytes()), + s: U256::from(transaction.signature.s().as_bytes()), + condition: None // TODO + } +} + +impl EthApi where + C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, + C::Api: EthereumRuntimeRPCApi, + BE: Backend + 'static, + BE::State: StateBackend, + B: BlockT + Send + Sync + 'static, + C: Send + Sync + 'static, + SC: SelectChain + Clone + 'static, + P: TransactionPool + Send + Sync + 'static, + CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, +{ + fn native_block_id(&self, number: Option) -> Result>> { + Ok(match number.unwrap_or(BlockNumber::Latest) { + BlockNumber::Hash { hash, .. } => { + self.load_hash(hash).unwrap_or(None) + }, + BlockNumber::Num(number) => { + Some(BlockId::Number(number.unique_saturated_into())) + }, + BlockNumber::Latest => { + Some(BlockId::Hash( + self.select_chain.best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? + .hash() + )) + }, + BlockNumber::Earliest => { + Some(BlockId::Number(Zero::zero())) + }, + BlockNumber::Pending => { + None + } + }) + } + + // Asumes there is only one mapped canonical block in the AuxStore, otherwise something is wrong + fn load_hash(&self, hash: H256) -> Result>> { + let hashes = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) + .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + { + Some(hashes) => hashes, + None => return Ok(None), + }; + let out: Vec = hashes.into_iter() + .filter_map(|h| { + if let Ok(Some(_)) = self.client.header(BlockId::Hash(h)) { + Some(h) + } else { + None + } + }).collect(); + + if out.len() == 1 { + return Ok(Some( + BlockId::Hash(out[0]) + )); + } + Ok(None) + } +} + +impl EthApiT for EthApi where + C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, + C::Api: EthereumRuntimeRPCApi, + BE: Backend + 'static, + BE::State: StateBackend, + B: BlockT + Send + Sync + 'static, + C: Send + Sync + 'static, + SC: SelectChain + Clone + 'static, + P: TransactionPool + Send + Sync + 'static, + CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, +{ + fn protocol_version(&self) -> Result { + Ok(1) + } + + fn syncing(&self) -> Result { + let header = self + .select_chain + .best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + + let block_number = U256::from(header.number().clone().unique_saturated_into()); + + Ok(SyncStatus::Info(SyncInfo { + starting_block: U256::zero(), + current_block: block_number, + highest_block: block_number, + warp_chunks_amount: None, + warp_chunks_processed: None, + })) + } + + fn hashrate(&self) -> Result { + Ok(U256::zero()) + } + + fn author(&self) -> Result { + let header = self.select_chain + .best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + + Ok( + self.client + .runtime_api() + .author(&BlockId::Hash(header.hash())) + .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))?.into() + ) + } + + fn is_mining(&self) -> Result { + Ok(self.is_authority) + } + + fn chain_id(&self) -> Result> { + let header = self.select_chain.best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + Ok(Some(self.client.runtime_api().chain_id(&BlockId::Hash(header.hash())) + .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))?.into())) + } + + fn gas_price(&self) -> Result { + let header = self + .select_chain + .best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + Ok( + self.client + .runtime_api() + .gas_price(&BlockId::Hash(header.hash())) + .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? + .into(), + ) + } + + fn accounts(&self) -> Result> { + Ok(vec![]) + } + + fn block_number(&self) -> Result { + let header = self + .select_chain + .best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + Ok(U256::from(header.number().clone().unique_saturated_into())) + } + + fn balance(&self, address: H160, number: Option) -> Result { + if let Ok(Some(id)) = self.native_block_id(number) { + return Ok( + self.client + .runtime_api() + .account_basic(&id, address) + .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? + .balance.into(), + ); + } + Ok(U256::zero()) + } + + fn storage_at(&self, address: H160, index: U256, number: Option) -> Result { + if let Ok(Some(id)) = self.native_block_id(number) { + return Ok( + self.client + .runtime_api() + .storage_at(&id, address, index) + .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? + .into(), + ); + } + Ok(H256::default()) + } + + fn block_by_hash(&self, hash: H256, full: bool) -> Result> { + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? + { + Some(hash) => hash, + _ => return Ok(None), + }; + + let block = self.client.runtime_api().current_block(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + let statuses = self.client.runtime_api().current_transaction_statuses(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + match (block, statuses) { + (Some(block), Some(statuses)) => { + Ok(Some(rich_block_build( + block, + statuses.into_iter().map(|s| Some(s)).collect(), + Some(hash), + full, + ))) + }, + _ => { + Ok(None) + }, + } + } + + fn block_by_number(&self, number: BlockNumber, full: bool) -> Result> { + let id = match self.native_block_id(Some(number))? { + Some(id) => id, + None => return Ok(None), + }; + + let block = self.client.runtime_api().current_block(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + let statuses = self.client.runtime_api().current_transaction_statuses(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + match (block, statuses) { + (Some(block), Some(statuses)) => { + let hash = H256::from_slice( + Keccak256::digest(&rlp::encode(&block.header)).as_slice(), + ); + + Ok(Some(rich_block_build( + block, + statuses.into_iter().map(|s| Some(s)).collect(), + Some(hash), + full, + ))) + }, + _ => { + Ok(None) + }, + } + } + + fn transaction_count(&self, address: H160, number: Option) -> Result { + let id = match self.native_block_id(number)? { + Some(id) => id, + None => return Ok(U256::zero()), + }; + + let nonce = self.client.runtime_api() + .account_basic(&id, address) + .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))? + .nonce.into(); + + Ok(nonce) + } + + fn block_transaction_count_by_hash(&self, hash: H256) -> Result> { + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? + { + Some(hash) => hash, + _ => return Ok(None), + }; + + let block = self.client.runtime_api() + .current_block(&id) + .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; + + match block { + Some(block) => Ok(Some(U256::from(block.transactions.len()))), + None => Ok(None), + } + } + + fn block_transaction_count_by_number(&self, number: BlockNumber) -> Result> { + let id = match self.native_block_id(Some(number))? { + Some(id) => id, + None => return Ok(None), + }; + + let block = self.client.runtime_api() + .current_block(&id) + .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; + + match block { + Some(block) => Ok(Some(U256::from(block.transactions.len()))), + None => Ok(None), + } + } + + fn block_uncles_count_by_hash(&self, _: H256) -> Result { + Ok(U256::zero()) + } + + fn block_uncles_count_by_number(&self, _: BlockNumber) -> Result { + Ok(U256::zero()) + } + + fn code_at(&self, address: H160, number: Option) -> Result { + if let Ok(Some(id)) = self.native_block_id(number) { + return Ok( + self.client + .runtime_api() + .account_code_at(&id, address) + .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? + .into(), + ); + } + Ok(Bytes(vec![])) + } + + fn send_raw_transaction(&self, bytes: Bytes) -> BoxFuture { + let transaction = match rlp::decode::(&bytes.0[..]) { + Ok(transaction) => transaction, + Err(_) => return Box::new( + future::result(Err(internal_err("decode transaction failed"))) + ), + }; + let transaction_hash = H256::from_slice( + Keccak256::digest(&rlp::encode(&transaction)).as_slice() + ); + let header = match self.select_chain.best_chain() { + Ok(header) => header, + Err(_) => return Box::new( + future::result(Err(internal_err("fetch header failed"))) + ), + }; + let best_block_hash = header.hash(); + Box::new( + self.pool + .submit_one( + &BlockId::hash(best_block_hash), + TransactionSource::Local, + self.convert_transaction.convert_transaction(transaction), + ) + .compat() + .map(move |_| transaction_hash) + .map_err(|err| internal_err(format!("submit transaction to pool failed: {:?}", err))) + ) + } + + fn call(&self, request: CallRequest, _: Option) -> Result { + let header = self + .select_chain + .best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + + let from = request.from.unwrap_or_default(); + let to = request.to.unwrap_or_default(); + let gas_price = request.gas_price; + let gas_limit = request.gas.unwrap_or(U256::max_value()); + let value = request.value.unwrap_or_default(); + let data = request.data.map(|d| d.0).unwrap_or_default(); + let nonce = request.nonce; + + let (ret, _) = self.client.runtime_api() + .call( + &BlockId::Hash(header.hash()), + from, + data, + value, + gas_limit, + gas_price, + nonce, + ethereum::TransactionAction::Call(to) + ) + .map_err(|err| internal_err(format!("internal error: {:?}", err)))? + .map_err(|err| internal_err(format!("executing call failed: {:?}", err)))?; + + Ok(Bytes(ret)) + } + + fn estimate_gas(&self, request: CallRequest, _: Option) -> Result { + let header = self + .select_chain + .best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + + let from = request.from.unwrap_or_default(); + let gas_price = request.gas_price; + let gas_limit = request.gas.unwrap_or(U256::max_value()); // TODO: this isn't safe + let value = request.value.unwrap_or_default(); + let data = request.data.map(|d| d.0).unwrap_or_default(); + let nonce = request.nonce; + + let (_, used_gas) = self.client.runtime_api() + .call( + &BlockId::Hash(header.hash()), + from, + data, + value, + gas_limit, + gas_price, + nonce, + match request.to { + Some(to) => ethereum::TransactionAction::Call(to), + _ => ethereum::TransactionAction::Create, + } + ) + .map_err(|err| internal_err(format!("internal error: {:?}", err)))? + .map_err(|err| internal_err(format!("executing call failed: {:?}", err)))?; + + Ok(used_gas) + } + + fn transaction_by_hash(&self, hash: H256) -> Result> { + let (hash, index) = match frontier_consensus::load_transaction_metadata( + self.client.as_ref(), + hash, + ).map_err(|err| internal_err(format!("fetch aux store failed: {:?})", err)))? { + Some((hash, index)) => (hash, index as usize), + None => return Ok(None), + }; + + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? + { + Some(hash) => hash, + _ => return Ok(None), + }; + + let block = self.client.runtime_api().current_block(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + let statuses = self.client.runtime_api().current_transaction_statuses(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + match (block, statuses) { + (Some(block), Some(statuses)) => { + Ok(Some(transaction_build( + block.transactions[index].clone(), + block, + statuses[index].clone(), + ))) + }, + _ => Ok(None) + } + } + + fn transaction_by_block_hash_and_index( + &self, + hash: H256, + index: Index, + ) -> Result> { + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? + { + Some(hash) => hash, + _ => return Ok(None), + }; + let index = index.value(); + + let block = self.client.runtime_api().current_block(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + let statuses = self.client.runtime_api().current_transaction_statuses(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + match (block, statuses) { + (Some(block), Some(statuses)) => { + Ok(Some(transaction_build( + block.transactions[index].clone(), + block, + statuses[index].clone(), + ))) + }, + _ => Ok(None) + } + } + + fn transaction_by_block_number_and_index( + &self, + number: BlockNumber, + index: Index, + ) -> Result> { + let id = match self.native_block_id(Some(number))? { + Some(id) => id, + None => return Ok(None), + }; + let index = index.value(); + + let block = self.client.runtime_api().current_block(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + let statuses = self.client.runtime_api().current_transaction_statuses(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + match (block, statuses) { + (Some(block), Some(statuses)) => { + Ok(Some(transaction_build( + block.transactions[index].clone(), + block, + statuses[index].clone(), + ))) + }, + _ => Ok(None) + } + } + + fn transaction_receipt(&self, hash: H256) -> Result> { + let (hash, index) = match frontier_consensus::load_transaction_metadata( + self.client.as_ref(), + hash, + ).map_err(|err| internal_err(format!("fetch aux store failed : {:?}", err)))? { + Some((hash, index)) => (hash, index as usize), + None => return Ok(None), + }; + + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? + { + Some(hash) => hash, + _ => return Ok(None), + }; + + let block = self.client.runtime_api().current_block(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + let receipts = self.client.runtime_api().current_receipts(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + let statuses = self.client.runtime_api().current_transaction_statuses(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + match (block, statuses, receipts) { + (Some(block), Some(statuses), Some(receipts)) => { + let block_hash = H256::from_slice( + Keccak256::digest(&rlp::encode(&block.header)).as_slice() + ); + let receipt = receipts[index].clone(); + let status = statuses[index].clone(); + let mut cumulative_receipts = receipts.clone(); + cumulative_receipts.truncate((status.transaction_index + 1) as usize); + + return Ok(Some(Receipt { + transaction_hash: Some(status.transaction_hash), + transaction_index: Some(status.transaction_index.into()), + block_hash: Some(block_hash), + from: Some(status.from), + to: status.to, + block_number: Some(block.header.number), + cumulative_gas_used: { + let cumulative_gas: u32 = cumulative_receipts.iter().map(|r| { + r.used_gas.as_u32() + }).sum(); + U256::from(cumulative_gas) + }, + gas_used: Some(receipt.used_gas), + contract_address: status.contract_address, + logs: { + let mut pre_receipts_log_index = None; + if cumulative_receipts.len() > 0 { + cumulative_receipts.truncate(cumulative_receipts.len() - 1); + pre_receipts_log_index = Some(cumulative_receipts.iter().map(|r| { + r.logs.len() as u32 + }).sum::()); + } + receipt.logs.iter().enumerate().map(|(i, log)| { + Log { + address: log.address, + topics: log.topics.clone(), + data: Bytes(log.data.clone()), + block_hash: Some(block_hash), + block_number: Some(block.header.number), + transaction_hash: Some(hash), + transaction_index: Some(status.transaction_index.into()), + log_index: Some(U256::from( + (pre_receipts_log_index.unwrap_or(0)) + i as u32 + )), + transaction_log_index: Some(U256::from(i)), + removed: false, + } + }).collect() + }, + state_root: Some(receipt.state_root), + logs_bloom: receipt.logs_bloom, + status_code: None, + })) + } + _ => Ok(None), + } + } + + fn uncle_by_block_hash_and_index(&self, _: H256, _: Index) -> Result> { + Ok(None) + } + + fn uncle_by_block_number_and_index( + &self, + _: BlockNumber, + _: Index, + ) -> Result> { + Ok(None) + } + + fn logs(&self, filter: Filter) -> Result> { + let mut blocks_and_receipts = Vec::new(); + let mut ret = Vec::new(); + + if let Some(hash) = filter.block_hash { + let id = match self.load_hash(hash) + .map_err(|err| internal_err(format!("{:?}", err)))? + { + Some(hash) => hash, + _ => return Ok(Vec::new()), + }; + + let block = self.client.runtime_api() + .current_block(&id) + .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; + let receipts = self.client.runtime_api().current_receipts(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + if let (Some(block), Some(receipts)) = (block, receipts) { + blocks_and_receipts.push((block, receipts)); + } + } else { + let mut current_number = filter.to_block + .and_then(|v| v.to_min_block_num()) + .map(|s| s.unique_saturated_into()) + .unwrap_or( + *self.select_chain.best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? + .number() + ); + + let from_number = filter.from_block + .and_then(|v| v.to_min_block_num()) + .map(|s| s.unique_saturated_into()) + .unwrap_or( + *self.select_chain.best_chain() + .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? + .number() + ); + + while current_number >= from_number { + let id = BlockId::Number(current_number); + + let block = self.client.runtime_api() + .current_block(&id) + .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; + let receipts = self.client.runtime_api().current_receipts(&id) + .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; + + if let (Some(block), Some(receipts)) = (block, receipts) { + blocks_and_receipts.push((block, receipts)); + } + + if current_number == Zero::zero() { + break + } else { + current_number = current_number.saturating_sub(One::one()); + } + } + } + + for (block, receipts) in blocks_and_receipts { + let mut block_log_index: u32 = 0; + for (index, receipt) in receipts.iter().enumerate() { + let logs = receipt.logs.clone(); + let mut transaction_log_index: u32 = 0; + let transaction = &block.transactions[index as usize]; + let transaction_hash = H256::from_slice( + Keccak256::digest(&rlp::encode(transaction)).as_slice() + ); + for log in logs { + let mut add: bool = false; + if let ( + Some(VariadicValue::Single(address)), + Some(VariadicValue::Multiple(topics)) + ) = ( + filter.address.clone(), + filter.topics.clone(), + ) { + if address == log.address && log.topics.starts_with(&topics) { + add = true; + } + } else if let Some(VariadicValue::Single(address)) = filter.address { + if address == log.address { + add = true; + } + } else if let Some(VariadicValue::Multiple(topics)) = &filter.topics { + if log.topics.starts_with(&topics) { + add = true; + } + } + if add { + ret.push(Log { + address: log.address.clone(), + topics: log.topics.clone(), + data: Bytes(log.data.clone()), + block_hash: Some(H256::from_slice( + Keccak256::digest(&rlp::encode(&block.header)).as_slice() + )), + block_number: Some(block.header.number.clone()), + transaction_hash: Some(transaction_hash), + transaction_index: Some(U256::from(index)), + log_index: Some(U256::from(block_log_index)), + transaction_log_index: Some(U256::from(transaction_log_index)), + removed: false, + }); + } + transaction_log_index += 1; + block_log_index += 1; + } + } + } + + Ok(ret) + } + + fn work(&self) -> Result { + Ok(Work { + pow_hash: H256::default(), + seed_hash: H256::default(), + target: H256::default(), + number: None, + }) + } + + fn submit_work(&self, _: H64, _: H256, _: H256) -> Result { + Ok(false) + } + + fn submit_hashrate(&self, _: U256, _: H256) -> Result { + Ok(false) + } +} + +pub struct NetApi { + select_chain: SC, + client: Arc, + _marker: PhantomData<(B, BE)>, +} + +impl NetApi { + pub fn new( + client: Arc, + select_chain: SC, + ) -> Self { + Self { + client: client, + select_chain: select_chain, + _marker: PhantomData, + } + } +} + +impl NetApiT for NetApi where + C: ProvideRuntimeApi + StorageProvider + AuxStore, + C::Api: EthereumRuntimeRPCApi, + BE: Backend + 'static, + BE::State: StateBackend, + C: Send + Sync + 'static, + SC: SelectChain + Clone + 'static, + B: BlockT + Send + Sync + 'static, +{ + fn is_listening(&self) -> Result { + Ok(true) + } + + fn peer_count(&self) -> Result { + Ok("0".to_string()) + } + + fn version(&self) -> Result { + let header = self.select_chain.best_chain() + .map_err(|_| internal_err("fetch header failed"))?; + Ok(self.client.runtime_api().chain_id(&BlockId::Hash(header.hash())) + .map_err(|_| internal_err("fetch runtime chain id failed"))?.to_string()) + } +} diff --git a/rpc/src/eth_pubsub.rs b/rpc/src/eth_pubsub.rs new file mode 100644 index 0000000000..a9701772e9 --- /dev/null +++ b/rpc/src/eth_pubsub.rs @@ -0,0 +1,566 @@ +use std::{marker::PhantomData, sync::Arc}; +use std::collections::BTreeMap; +use sp_runtime::traits::{ + Block as BlockT, Header as _, BlakeTwo256, + UniqueSaturatedInto +}; +use sp_transaction_pool::TransactionPool; +use sp_api::{ProvideRuntimeApi, BlockId}; +use sp_blockchain::HeaderBackend; +use sp_storage::{StorageKey, StorageData}; +use sp_io::hashing::twox_128; +use sc_client_api::{ + backend::{StorageProvider, Backend, StateBackend, AuxStore}, + client::BlockchainEvents +}; +use sc_rpc::Metadata; +use sp_consensus::SelectChain; +use log::warn; + +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; +use frontier_rpc_core::EthPubSubApi::{self as EthPubSubApiT}; +use frontier_rpc_core::types::{ + BlockNumber, Rich, Header, Bytes, Log, FilterAddress, Topic, VariadicValue, + pubsub::{Kind, Params, Result as PubSubResult, PubSubSyncStatus} +}; +use ethereum_types::{H256, U256}; +use codec::Decode; +use sha3::{Keccak256, Digest}; + +pub use frontier_rpc_core::EthPubSubApiServer; +use futures::{StreamExt as _, TryStreamExt as _}; + +use jsonrpc_core::{Result as JsonRpcResult, futures::{Future, Sink}}; +use frontier_rpc_primitives::{EthereumRuntimeRPCApi, TransactionStatus}; + +use sc_network::{NetworkService, ExHashT}; +use crate::internal_err; + +pub struct EthPubSubApi { + _pool: Arc

, + client: Arc, + select_chain: SC, + network: Arc>, + subscriptions: SubscriptionManager, + _marker: PhantomData<(B, BE)>, +} + +impl EthPubSubApi { + pub fn new( + _pool: Arc

, + client: Arc, + select_chain: SC, + network: Arc>, + subscriptions: SubscriptionManager, + ) -> Self { + Self { _pool, client, select_chain, network, subscriptions, _marker: PhantomData } + } +} + +impl EthPubSubApi where + B: BlockT + Send + Sync + 'static, + P: TransactionPool + Send + Sync + 'static, + C: ProvideRuntimeApi + StorageProvider + + BlockchainEvents + HeaderBackend + AuxStore, + C::Api: EthereumRuntimeRPCApi, + C: Send + Sync + 'static, + BE: Backend + 'static, + BE::State: StateBackend, + SC: SelectChain + Clone + 'static, +{ + fn native_block_number(&self, number: Option) -> JsonRpcResult> { + let header = self + .select_chain + .best_chain() + .map_err(|_| internal_err("fetch header failed"))?; + + let mut native_number: Option = None; + + if let Some(number) = number { + match number { + BlockNumber::Hash { hash, .. } => { + let id = self.load_hash(hash).unwrap_or(None); + if let Some(id) = id { + if let Ok(Some(block)) = self.client.runtime_api().current_block(&id) { + native_number = Some(block.header.number.as_u32()); + } + } + }, + BlockNumber::Num(_) => { + if let Some(number) = number.to_min_block_num() { + native_number = Some(number.unique_saturated_into()); + } + }, + BlockNumber::Latest => { + native_number = Some( + header.number().clone().unique_saturated_into() as u32 + ); + }, + BlockNumber::Earliest => { + native_number = Some(0); + }, + BlockNumber::Pending => { + native_number = None; + } + }; + } else { + native_number = Some( + header.number().clone().unique_saturated_into() as u32 + ); + } + Ok(native_number) + } + + fn filter_block( + &self, + params: Option + ) -> (Option, Option) { + if let Some(Params::Logs(f)) = params { + return ( + self.native_block_number(f.from_block).unwrap_or(None), + self.native_block_number(f.to_block).unwrap_or(None) + ); + } + (None, None) + } + + // Asumes there is only one mapped canonical block in the AuxStore, otherwise something is wrong + fn load_hash(&self, hash: H256) -> JsonRpcResult>> { + let hashes = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) + .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? + { + Some(hashes) => hashes, + None => return Ok(None), + }; + let out: Vec = hashes.into_iter() + .filter_map(|h| { + if let Ok(Some(_)) = self.client.header(BlockId::Hash(h)) { + Some(h) + } else { + None + } + }).collect(); + + if out.len() == 1 { + return Ok(Some( + BlockId::Hash(out[0]) + )); + } + Ok(None) + } +} + +struct FilteredParams { + from_block: Option, + to_block: Option, + block_hash: Option, + address: Option, + topics: Option +} + +impl FilteredParams { + pub fn new( + params: Option, + block_range: (Option, Option) + ) -> Self { + if let Some(Params::Logs(d)) = params { + return FilteredParams { + from_block: block_range.0, + to_block: block_range.1, + block_hash: d.block_hash, + address: d.address, + topics: d.topics + }; + } + FilteredParams { + from_block: None, + to_block: None, + block_hash: None, + address: None, + topics: None + } + } + + pub fn filter_block_range( + &self, + block: ðereum::Block + ) -> bool { + let mut out = true; + let number: u32 = UniqueSaturatedInto::::unique_saturated_into( + block.header.number + ); + if let Some(from) = self.from_block { + if from > number { + out = false; + } + } + if let Some(to) = self.to_block { + if to < number { + out = false; + } + } + out + } + + fn filter_block_hash( + &self, + block_hash: H256 + ) -> bool { + if let Some(h) = self.block_hash { + if h != block_hash { return false; } + } + true + } + + fn filter_address( + &self, + log: ðereum::Log + ) -> bool { + if let Some(input_address) = &self.address { + match input_address { + VariadicValue::Single(x) => { + if log.address != *x { return false; } + }, + VariadicValue::Multiple(x) => { + if !x.contains(&log.address) { return false; } + }, + _ => { return true; } + } + } + true + } + + fn filter_topics( + &self, + log: ðereum::Log + ) -> bool { + if let Some(input_topics) = &self.topics { + match input_topics { + VariadicValue::Single(x) => { + if !log.topics.starts_with(&vec![*x]) { + return false; + } + }, + VariadicValue::Multiple(x) => { + if !log.topics.starts_with(&x) { + return false; + } + }, + _ => { return true; } + } + } + true + } +} + +struct SubscriptionResult {} +impl SubscriptionResult { + pub fn new() -> Self { SubscriptionResult{} } + pub fn new_heads(&self, block: ethereum::Block) -> PubSubResult { + PubSubResult::Header(Box::new( + Rich { + inner: Header { + hash: Some(H256::from_slice(Keccak256::digest( + &rlp::encode(&block.header) + ).as_slice())), + parent_hash: block.header.parent_hash, + uncles_hash: block.header.ommers_hash, + author: block.header.beneficiary, + miner: block.header.beneficiary, + state_root: block.header.state_root, + transactions_root: block.header.transactions_root, + receipts_root: block.header.receipts_root, + number: Some(block.header.number), + gas_used: block.header.gas_used, + gas_limit: block.header.gas_limit, + extra_data: Bytes( + block.header.extra_data.as_bytes().to_vec() + ), + logs_bloom: block.header.logs_bloom, + timestamp: U256::from(block.header.timestamp), + difficulty: block.header.difficulty, + seal_fields: vec![ + Bytes( + block.header.mix_hash.as_bytes().to_vec() + ), + Bytes( + block.header.nonce.as_bytes().to_vec() + ) + ], + size: Some(U256::from( + rlp::encode(&block).len() as u32 + )), + }, + extra_info: BTreeMap::new() + } + )) + } + pub fn logs( + &self, + block: ethereum::Block, + receipts: Vec, + params: &FilteredParams + ) -> Vec { + let block_hash = Some(H256::from_slice( + Keccak256::digest(&rlp::encode( + &block.header + )).as_slice() + )); + let mut logs: Vec = vec![]; + let mut log_index: u32 = 0; + for receipt in receipts { + let mut transaction_log_index: u32 = 0; + for log in receipt.logs { + if self.add_log( + block_hash.unwrap(), + &log, + &block, + params + ) { + logs.push(Log { + address: log.address, + topics: log.topics, + data: Bytes(log.data), + block_hash: block_hash, + block_number: Some(block.header.number), + transaction_hash: Some(H256::from_slice( + Keccak256::digest(&rlp::encode( + &block.transactions[log_index as usize] + )).as_slice() + )), + transaction_index: Some(U256::from(log_index)), + log_index: Some(U256::from(log_index)), + transaction_log_index: Some(U256::from( + transaction_log_index + )), + removed: false, + }); + } + log_index += 1; + transaction_log_index += 1; + } + } + logs + } + fn add_log( + &self, + block_hash: H256, + log: ðereum::Log, + block: ðereum::Block, + params: &FilteredParams + ) -> bool { + if !params.filter_block_range(block) || + !params.filter_block_hash(block_hash) || + !params.filter_address(log) || !params.filter_topics(log) { + return false; + } + true + } +} + +fn storage_prefix_build(module: &[u8], storage: &[u8]) -> Vec { + [twox_128(module), twox_128(storage)].concat().to_vec() +} + +macro_rules! stream_build { + ($context:expr => $module:expr, $storage:expr) => {{ + let key: StorageKey = StorageKey( + storage_prefix_build($module, $storage) + ); + match $context.client.storage_changes_notification_stream( + Some(&[key]), + None + ) { + Ok(stream) => Some(stream), + Err(_err) => None, + } + }}; +} + +impl EthPubSubApiT for EthPubSubApi + where + B: BlockT + Send + Sync + 'static, + P: TransactionPool + Send + Sync + 'static, + C: ProvideRuntimeApi + StorageProvider + + BlockchainEvents + HeaderBackend + AuxStore, + C: Send + Sync + 'static, + C::Api: EthereumRuntimeRPCApi, + BE: Backend + 'static, + BE::State: StateBackend, + SC: SelectChain + Clone + 'static, +{ + type Metadata = Metadata; + fn subscribe( + &self, + _metadata: Self::Metadata, + subscriber: Subscriber, + kind: Kind, + params: Option, + ) { + let filter_block = self.filter_block(params.clone()); + let filtered_params = FilteredParams::new(params, filter_block); + let client = self.client.clone(); + let network = self.network.clone(); + match kind { + Kind::Logs => { + if let Some(stream) = stream_build!( + self => b"Ethereum", b"CurrentReceipts" + ) { + self.subscriptions.add(subscriber, |sink| { + let stream = stream + .flat_map(move |(block_hash, changes)| { + let id = BlockId::Hash(block_hash); + let data = changes.iter().last().unwrap().2.unwrap(); + let receipts: Vec = + Decode::decode(&mut &data.0[..]).unwrap(); + let block: ethereum::Block = client.runtime_api() + .current_block(&id).unwrap().unwrap(); + futures::stream::iter( + SubscriptionResult::new() + .logs(block, receipts, &filtered_params) + ) + }) + .map(|x| { + return Ok::, ()>(Ok( + PubSubResult::Log(Box::new(x)) + )); + }) + .compat(); + + sink + .sink_map_err(|e| warn!( + "Error sending notifications: {:?}", e + )) + .send_all(stream) + .map(|_| ()) + }); + } + }, + Kind::NewHeads => { + if let Some(stream) = stream_build!( + self => b"Ethereum", b"CurrentBlock" + ) { + self.subscriptions.add(subscriber, |sink| { + let stream = stream + .map(|(_block, changes)| { + let data = changes.iter().last().unwrap().2.unwrap(); + let block: ethereum::Block = + Decode::decode(&mut &data.0[..]).unwrap(); + return Ok::<_, ()>(Ok( + SubscriptionResult::new() + .new_heads(block) + )); + }) + .compat(); + + sink + .sink_map_err(|e| warn!( + "Error sending notifications: {:?}", e + )) + .send_all(stream) + .map(|_| ()) + }); + } + }, + Kind::NewPendingTransactions => { + if let Some(stream) = stream_build!( + self => b"Ethereum", b"Pending" + ) { + self.subscriptions.add(subscriber, |sink| { + let stream = stream + .flat_map(|(_block, changes)| { + let mut transactions: Vec = vec![]; + let storage: Vec> = changes.iter() + .filter_map(|(o_sk, _k, v)| { + if o_sk.is_none() { + Some(v.cloned()) + } else { None } + }).collect(); + for change in storage { + if let Some(data) = change { + let storage: Vec<( + ethereum::Transaction, + TransactionStatus, + ethereum::Receipt + )> = Decode::decode(&mut &data.0[..]).unwrap(); + let tmp: Vec = + storage.iter().map(|x| x.0.clone()).collect(); + transactions.extend(tmp); + } + } + futures::stream::iter(transactions) + }) + .map(|transaction| { + return Ok::, ()>(Ok( + PubSubResult::TransactionHash(H256::from_slice( + Keccak256::digest( + &rlp::encode(&transaction) + ).as_slice() + )) + )); + }) + .compat(); + + sink + .sink_map_err(|e| warn!( + "Error sending notifications: {:?}", e + )) + .send_all(stream) + .map(|_| ()) + }); + } + }, + Kind::Syncing => { + if let Some(stream) = stream_build!( + self => b"Ethereum", b"CurrentBlock" + ) { + self.subscriptions.add(subscriber, |sink| { + let mut previous_syncing = network.is_major_syncing(); + let stream = stream + .filter_map(move |(_, _)| { + let syncing = network.is_major_syncing(); + if previous_syncing != syncing { + previous_syncing = syncing; + futures::future::ready(Some(syncing)) + } else { + futures::future::ready(None) + } + }) + .map(|syncing| { + return Ok::, ()>(Ok( + PubSubResult::SyncState(PubSubSyncStatus { + syncing: syncing + }) + )); + }) + .compat(); + sink + .sink_map_err(|e| warn!( + "Error sending notifications: {:?}", e + )) + .send_all(stream) + .map(|_| ()) + + }); + } + }, + } + } + + fn unsubscribe( + &self, + _metadata: Option, + subscription_id: SubscriptionId + ) -> JsonRpcResult { + Ok(self.subscriptions.cancel(subscription_id)) + } +} diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index dabc1e2c19..62d4d6ef11 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -14,925 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{marker::PhantomData, sync::Arc}; -use std::collections::BTreeMap; -use ethereum::{Block as EthereumBlock, Transaction as EthereumTransaction}; -use ethereum_types::{H160, H256, H64, U256, U64, H512}; -use jsonrpc_core::{BoxFuture, Result, ErrorCode, Error, futures::future::{self, Future}}; -use futures::future::TryFutureExt; -use sp_runtime::traits::{Block as BlockT, Header as _, UniqueSaturatedInto, Zero, One, Saturating}; -use sp_runtime::transaction_validity::TransactionSource; -use sp_api::{ProvideRuntimeApi, BlockId}; -use sp_consensus::SelectChain; -use sp_transaction_pool::TransactionPool; -use sc_client_api::backend::{StorageProvider, Backend, StateBackend, AuxStore}; -use sha3::{Keccak256, Digest}; -use sp_runtime::traits::BlakeTwo256; -use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; -use frontier_rpc_core::{EthApi as EthApiT, NetApi as NetApiT}; -use frontier_rpc_core::types::{ - BlockNumber, Bytes, CallRequest, Filter, Index, Log, Receipt, RichBlock, - SyncStatus, SyncInfo, Transaction, Work, Rich, Block, BlockTransactions, VariadicValue -}; -use frontier_rpc_primitives::{EthereumRuntimeRPCApi, ConvertTransaction, TransactionStatus}; +mod eth; +mod eth_pubsub; -pub use frontier_rpc_core::{EthApiServer, NetApiServer}; +pub use eth::{EthApi, EthApiServer, NetApi, NetApiServer}; +pub use eth_pubsub::{EthPubSubApi, EthPubSubApiServer}; -fn internal_err(message: T) -> Error { +use jsonrpc_core::{ErrorCode, Error}; + +pub fn internal_err(message: T) -> Error { Error { code: ErrorCode::InternalError, message: message.to_string(), data: None } } - -pub struct EthApi { - pool: Arc

, - client: Arc, - select_chain: SC, - convert_transaction: CT, - is_authority: bool, - _marker: PhantomData<(B, BE)>, -} - -impl EthApi { - pub fn new( - client: Arc, - select_chain: SC, - pool: Arc

, - convert_transaction: CT, - is_authority: bool - ) -> Self { - Self { client, select_chain, pool, convert_transaction, is_authority, _marker: PhantomData } - } -} - -fn rich_block_build( - block: ethereum::Block, - statuses: Vec>, - hash: Option, - full_transactions: bool -) -> RichBlock { - Rich { - inner: Block { - hash: Some(hash.unwrap_or_else(|| { - H256::from_slice( - Keccak256::digest(&rlp::encode(&block.header)).as_slice() - ) - })), - parent_hash: block.header.parent_hash, - uncles_hash: H256::zero(), - author: block.header.beneficiary, - miner: block.header.beneficiary, - state_root: block.header.state_root, - transactions_root: block.header.transactions_root, - receipts_root: block.header.receipts_root, - number: Some(block.header.number), - gas_used: block.header.gas_used, - gas_limit: block.header.gas_limit, - extra_data: Bytes(block.header.extra_data.as_bytes().to_vec()), - logs_bloom: Some(block.header.logs_bloom), - timestamp: U256::from(block.header.timestamp / 1000), - difficulty: block.header.difficulty, - total_difficulty: None, - seal_fields: vec![ - Bytes(block.header.mix_hash.as_bytes().to_vec()), - Bytes(block.header.nonce.as_bytes().to_vec()) - ], - uncles: vec![], - transactions: { - if full_transactions { - BlockTransactions::Full( - block.transactions.iter().enumerate().map(|(index, transaction)|{ - transaction_build( - transaction.clone(), - block.clone(), - statuses[index].clone().unwrap_or_default() - ) - }).collect() - ) - } else { - BlockTransactions::Hashes( - block.transactions.iter().map(|transaction|{ - H256::from_slice( - Keccak256::digest(&rlp::encode(&transaction.clone())).as_slice() - ) - }).collect() - ) - } - }, - size: Some(U256::from(rlp::encode(&block).len() as u32)) - }, - extra_info: BTreeMap::new() - } -} - -fn transaction_build( - transaction: EthereumTransaction, - block: EthereumBlock, - status: TransactionStatus -) -> Transaction { - let mut sig = [0u8; 65]; - let mut msg = [0u8; 32]; - sig[0..32].copy_from_slice(&transaction.signature.r()[..]); - sig[32..64].copy_from_slice(&transaction.signature.s()[..]); - sig[64] = transaction.signature.standard_v(); - msg.copy_from_slice(&transaction.message_hash( - transaction.signature.chain_id().map(u64::from) - )[..]); - - let pubkey = match sp_io::crypto::secp256k1_ecdsa_recover(&sig, &msg) { - Ok(p) => Some(H512::from(p)), - Err(_e) => None, - }; - - Transaction { - hash: H256::from_slice( - Keccak256::digest(&rlp::encode(&transaction)).as_slice() - ), - nonce: transaction.nonce, - block_hash: Some(H256::from_slice( - Keccak256::digest(&rlp::encode(&block.header)).as_slice() - )), - block_number: Some(block.header.number), - transaction_index: Some(U256::from( - UniqueSaturatedInto::::unique_saturated_into( - status.transaction_index - ) - )), - from: status.from, - to: status.to, - value: transaction.value, - gas_price: transaction.gas_price, - gas: transaction.gas_limit, - input: Bytes(transaction.clone().input), - creates: status.contract_address, - raw: Bytes(rlp::encode(&transaction)), - public_key: pubkey, - chain_id: transaction.signature.chain_id().map(U64::from), - standard_v: U256::from(transaction.signature.standard_v()), - v: U256::from(transaction.signature.v()), - r: U256::from(transaction.signature.r().as_bytes()), - s: U256::from(transaction.signature.s().as_bytes()), - condition: None // TODO - } -} - -impl EthApi where - C: ProvideRuntimeApi + StorageProvider + AuxStore, - C: HeaderBackend + HeaderMetadata + 'static, - C::Api: EthereumRuntimeRPCApi, - BE: Backend + 'static, - BE::State: StateBackend, - B: BlockT + Send + Sync + 'static, - C: Send + Sync + 'static, - SC: SelectChain + Clone + 'static, - P: TransactionPool + Send + Sync + 'static, - CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, -{ - fn native_block_id(&self, number: Option) -> Result>> { - Ok(match number.unwrap_or(BlockNumber::Latest) { - BlockNumber::Hash { hash, .. } => { - self.load_hash(hash).unwrap_or(None) - }, - BlockNumber::Num(number) => { - Some(BlockId::Number(number.unique_saturated_into())) - }, - BlockNumber::Latest => { - Some(BlockId::Hash( - self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? - .hash() - )) - }, - BlockNumber::Earliest => { - Some(BlockId::Number(Zero::zero())) - }, - BlockNumber::Pending => { - None - } - }) - } - - // Asumes there is only one mapped canonical block in the AuxStore, otherwise something is wrong - fn load_hash(&self, hash: H256) -> Result>> { - let hashes = match frontier_consensus::load_block_hash::(self.client.as_ref(), hash) - .map_err(|err| internal_err(format!("fetch aux store failed: {:?}", err)))? - { - Some(hashes) => hashes, - None => return Ok(None), - }; - let out: Vec = hashes.into_iter() - .filter_map(|h| { - if let Ok(Some(_)) = self.client.header(BlockId::Hash(h)) { - Some(h) - } else { - None - } - }).collect(); - - if out.len() == 1 { - return Ok(Some( - BlockId::Hash(out[0]) - )); - } - Ok(None) - } -} - -impl EthApiT for EthApi where - C: ProvideRuntimeApi + StorageProvider + AuxStore, - C: HeaderBackend + HeaderMetadata + 'static, - C::Api: EthereumRuntimeRPCApi, - BE: Backend + 'static, - BE::State: StateBackend, - B: BlockT + Send + Sync + 'static, - C: Send + Sync + 'static, - SC: SelectChain + Clone + 'static, - P: TransactionPool + Send + Sync + 'static, - CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, -{ - fn protocol_version(&self) -> Result { - Ok(1) - } - - fn syncing(&self) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - - let block_number = U256::from(header.number().clone().unique_saturated_into()); - - Ok(SyncStatus::Info(SyncInfo { - starting_block: U256::zero(), - current_block: block_number, - highest_block: block_number, - warp_chunks_amount: None, - warp_chunks_processed: None, - })) - } - - fn hashrate(&self) -> Result { - Ok(U256::zero()) - } - - fn author(&self) -> Result { - let header = self.select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - - Ok( - self.client - .runtime_api() - .author(&BlockId::Hash(header.hash())) - .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))?.into() - ) - } - - fn is_mining(&self) -> Result { - Ok(self.is_authority) - } - - fn chain_id(&self) -> Result> { - let header = self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - Ok(Some(self.client.runtime_api().chain_id(&BlockId::Hash(header.hash())) - .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))?.into())) - } - - fn gas_price(&self) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - Ok( - self.client - .runtime_api() - .gas_price(&BlockId::Hash(header.hash())) - .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? - .into(), - ) - } - - fn accounts(&self) -> Result> { - Ok(vec![]) - } - - fn block_number(&self) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - Ok(U256::from(header.number().clone().unique_saturated_into())) - } - - fn balance(&self, address: H160, number: Option) -> Result { - if let Ok(Some(id)) = self.native_block_id(number) { - return Ok( - self.client - .runtime_api() - .account_basic(&id, address) - .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? - .balance.into(), - ); - } - Ok(U256::zero()) - } - - fn storage_at(&self, address: H160, index: U256, number: Option) -> Result { - if let Ok(Some(id)) = self.native_block_id(number) { - return Ok( - self.client - .runtime_api() - .storage_at(&id, address, index) - .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? - .into(), - ); - } - Ok(H256::default()) - } - - fn block_by_hash(&self, hash: H256, full: bool) -> Result> { - let id = match self.load_hash(hash) - .map_err(|err| internal_err(format!("{:?}", err)))? - { - Some(hash) => hash, - _ => return Ok(None), - }; - - let block = self.client.runtime_api().current_block(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - let statuses = self.client.runtime_api().current_transaction_statuses(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - match (block, statuses) { - (Some(block), Some(statuses)) => { - Ok(Some(rich_block_build( - block, - statuses.into_iter().map(|s| Some(s)).collect(), - Some(hash), - full, - ))) - }, - _ => { - Ok(None) - }, - } - } - - fn block_by_number(&self, number: BlockNumber, full: bool) -> Result> { - let id = match self.native_block_id(Some(number))? { - Some(id) => id, - None => return Ok(None), - }; - - let block = self.client.runtime_api().current_block(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - let statuses = self.client.runtime_api().current_transaction_statuses(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - match (block, statuses) { - (Some(block), Some(statuses)) => { - let hash = H256::from_slice( - Keccak256::digest(&rlp::encode(&block.header)).as_slice(), - ); - - Ok(Some(rich_block_build( - block, - statuses.into_iter().map(|s| Some(s)).collect(), - Some(hash), - full, - ))) - }, - _ => { - Ok(None) - }, - } - } - - fn transaction_count(&self, address: H160, number: Option) -> Result { - let id = match self.native_block_id(number)? { - Some(id) => id, - None => return Ok(U256::zero()), - }; - - let nonce = self.client.runtime_api() - .account_basic(&id, address) - .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))? - .nonce.into(); - - Ok(nonce) - } - - fn block_transaction_count_by_hash(&self, hash: H256) -> Result> { - let id = match self.load_hash(hash) - .map_err(|err| internal_err(format!("{:?}", err)))? - { - Some(hash) => hash, - _ => return Ok(None), - }; - - let block = self.client.runtime_api() - .current_block(&id) - .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; - - match block { - Some(block) => Ok(Some(U256::from(block.transactions.len()))), - None => Ok(None), - } - } - - fn block_transaction_count_by_number(&self, number: BlockNumber) -> Result> { - let id = match self.native_block_id(Some(number))? { - Some(id) => id, - None => return Ok(None), - }; - - let block = self.client.runtime_api() - .current_block(&id) - .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; - - match block { - Some(block) => Ok(Some(U256::from(block.transactions.len()))), - None => Ok(None), - } - } - - fn block_uncles_count_by_hash(&self, _: H256) -> Result { - Ok(U256::zero()) - } - - fn block_uncles_count_by_number(&self, _: BlockNumber) -> Result { - Ok(U256::zero()) - } - - fn code_at(&self, address: H160, number: Option) -> Result { - if let Ok(Some(id)) = self.native_block_id(number) { - return Ok( - self.client - .runtime_api() - .account_code_at(&id, address) - .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? - .into(), - ); - } - Ok(Bytes(vec![])) - } - - fn send_raw_transaction(&self, bytes: Bytes) -> BoxFuture { - let transaction = match rlp::decode::(&bytes.0[..]) { - Ok(transaction) => transaction, - Err(_) => return Box::new( - future::result(Err(internal_err("decode transaction failed"))) - ), - }; - let transaction_hash = H256::from_slice( - Keccak256::digest(&rlp::encode(&transaction)).as_slice() - ); - let header = match self.select_chain.best_chain() { - Ok(header) => header, - Err(_) => return Box::new( - future::result(Err(internal_err("fetch header failed"))) - ), - }; - let best_block_hash = header.hash(); - Box::new( - self.pool - .submit_one( - &BlockId::hash(best_block_hash), - TransactionSource::Local, - self.convert_transaction.convert_transaction(transaction), - ) - .compat() - .map(move |_| transaction_hash) - .map_err(|err| internal_err(format!("submit transaction to pool failed: {:?}", err))) - ) - } - - fn call(&self, request: CallRequest, _: Option) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - - let from = request.from.unwrap_or_default(); - let to = request.to.unwrap_or_default(); - let gas_price = request.gas_price; - let gas_limit = request.gas.unwrap_or(U256::max_value()); - let value = request.value.unwrap_or_default(); - let data = request.data.map(|d| d.0).unwrap_or_default(); - let nonce = request.nonce; - - let (ret, _) = self.client.runtime_api() - .call( - &BlockId::Hash(header.hash()), - from, - data, - value, - gas_limit, - gas_price, - nonce, - ethereum::TransactionAction::Call(to) - ) - .map_err(|err| internal_err(format!("internal error: {:?}", err)))? - .map_err(|err| internal_err(format!("executing call failed: {:?}", err)))?; - - Ok(Bytes(ret)) - } - - fn estimate_gas(&self, request: CallRequest, _: Option) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - - let from = request.from.unwrap_or_default(); - let gas_price = request.gas_price; - let gas_limit = request.gas.unwrap_or(U256::max_value()); // TODO: this isn't safe - let value = request.value.unwrap_or_default(); - let data = request.data.map(|d| d.0).unwrap_or_default(); - let nonce = request.nonce; - - let (_, used_gas) = self.client.runtime_api() - .call( - &BlockId::Hash(header.hash()), - from, - data, - value, - gas_limit, - gas_price, - nonce, - match request.to { - Some(to) => ethereum::TransactionAction::Call(to), - _ => ethereum::TransactionAction::Create, - } - ) - .map_err(|err| internal_err(format!("internal error: {:?}", err)))? - .map_err(|err| internal_err(format!("executing call failed: {:?}", err)))?; - - Ok(used_gas) - } - - fn transaction_by_hash(&self, hash: H256) -> Result> { - let (hash, index) = match frontier_consensus::load_transaction_metadata( - self.client.as_ref(), - hash, - ).map_err(|err| internal_err(format!("fetch aux store failed: {:?})", err)))? { - Some((hash, index)) => (hash, index as usize), - None => return Ok(None), - }; - - let id = match self.load_hash(hash) - .map_err(|err| internal_err(format!("{:?}", err)))? - { - Some(hash) => hash, - _ => return Ok(None), - }; - - let block = self.client.runtime_api().current_block(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - let statuses = self.client.runtime_api().current_transaction_statuses(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - match (block, statuses) { - (Some(block), Some(statuses)) => { - Ok(Some(transaction_build( - block.transactions[index].clone(), - block, - statuses[index].clone(), - ))) - }, - _ => Ok(None) - } - } - - fn transaction_by_block_hash_and_index( - &self, - hash: H256, - index: Index, - ) -> Result> { - let id = match self.load_hash(hash) - .map_err(|err| internal_err(format!("{:?}", err)))? - { - Some(hash) => hash, - _ => return Ok(None), - }; - let index = index.value(); - - let block = self.client.runtime_api().current_block(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - let statuses = self.client.runtime_api().current_transaction_statuses(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - match (block, statuses) { - (Some(block), Some(statuses)) => { - Ok(Some(transaction_build( - block.transactions[index].clone(), - block, - statuses[index].clone(), - ))) - }, - _ => Ok(None) - } - } - - fn transaction_by_block_number_and_index( - &self, - number: BlockNumber, - index: Index, - ) -> Result> { - let id = match self.native_block_id(Some(number))? { - Some(id) => id, - None => return Ok(None), - }; - let index = index.value(); - - let block = self.client.runtime_api().current_block(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - let statuses = self.client.runtime_api().current_transaction_statuses(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - match (block, statuses) { - (Some(block), Some(statuses)) => { - Ok(Some(transaction_build( - block.transactions[index].clone(), - block, - statuses[index].clone(), - ))) - }, - _ => Ok(None) - } - } - - fn transaction_receipt(&self, hash: H256) -> Result> { - let (hash, index) = match frontier_consensus::load_transaction_metadata( - self.client.as_ref(), - hash, - ).map_err(|err| internal_err(format!("fetch aux store failed : {:?}", err)))? { - Some((hash, index)) => (hash, index as usize), - None => return Ok(None), - }; - - let id = match self.load_hash(hash) - .map_err(|err| internal_err(format!("{:?}", err)))? - { - Some(hash) => hash, - _ => return Ok(None), - }; - - let block = self.client.runtime_api().current_block(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - let receipts = self.client.runtime_api().current_receipts(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - let statuses = self.client.runtime_api().current_transaction_statuses(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - match (block, statuses, receipts) { - (Some(block), Some(statuses), Some(receipts)) => { - let block_hash = H256::from_slice( - Keccak256::digest(&rlp::encode(&block.header)).as_slice() - ); - let receipt = receipts[index].clone(); - let status = statuses[index].clone(); - let mut cumulative_receipts = receipts.clone(); - cumulative_receipts.truncate((status.transaction_index + 1) as usize); - - return Ok(Some(Receipt { - transaction_hash: Some(status.transaction_hash), - transaction_index: Some(status.transaction_index.into()), - block_hash: Some(block_hash), - from: Some(status.from), - to: status.to, - block_number: Some(block.header.number), - cumulative_gas_used: { - let cumulative_gas: u32 = cumulative_receipts.iter().map(|r| { - r.used_gas.as_u32() - }).sum(); - U256::from(cumulative_gas) - }, - gas_used: Some(receipt.used_gas), - contract_address: status.contract_address, - logs: { - let mut pre_receipts_log_index = None; - if cumulative_receipts.len() > 0 { - cumulative_receipts.truncate(cumulative_receipts.len() - 1); - pre_receipts_log_index = Some(cumulative_receipts.iter().map(|r| { - r.logs.len() as u32 - }).sum::()); - } - receipt.logs.iter().enumerate().map(|(i, log)| { - Log { - address: log.address, - topics: log.topics.clone(), - data: Bytes(log.data.clone()), - block_hash: Some(block_hash), - block_number: Some(block.header.number), - transaction_hash: Some(hash), - transaction_index: Some(status.transaction_index.into()), - log_index: Some(U256::from( - (pre_receipts_log_index.unwrap_or(0)) + i as u32 - )), - transaction_log_index: Some(U256::from(i)), - removed: false, - } - }).collect() - }, - state_root: Some(receipt.state_root), - logs_bloom: receipt.logs_bloom, - status_code: None, - })) - } - _ => Ok(None), - } - } - - fn uncle_by_block_hash_and_index(&self, _: H256, _: Index) -> Result> { - Ok(None) - } - - fn uncle_by_block_number_and_index( - &self, - _: BlockNumber, - _: Index, - ) -> Result> { - Ok(None) - } - - fn logs(&self, filter: Filter) -> Result> { - let mut blocks_and_receipts = Vec::new(); - let mut ret = Vec::new(); - - if let Some(hash) = filter.block_hash { - let id = match self.load_hash(hash) - .map_err(|err| internal_err(format!("{:?}", err)))? - { - Some(hash) => hash, - _ => return Ok(Vec::new()), - }; - - let block = self.client.runtime_api() - .current_block(&id) - .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; - let receipts = self.client.runtime_api().current_receipts(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - if let (Some(block), Some(receipts)) = (block, receipts) { - blocks_and_receipts.push((block, receipts)); - } - } else { - let mut current_number = filter.to_block - .and_then(|v| v.to_min_block_num()) - .map(|s| s.unique_saturated_into()) - .unwrap_or( - *self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? - .number() - ); - - let from_number = filter.from_block - .and_then(|v| v.to_min_block_num()) - .map(|s| s.unique_saturated_into()) - .unwrap_or( - *self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? - .number() - ); - - while current_number >= from_number { - let id = BlockId::Number(current_number); - - let block = self.client.runtime_api() - .current_block(&id) - .map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?; - let receipts = self.client.runtime_api().current_receipts(&id) - .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; - - if let (Some(block), Some(receipts)) = (block, receipts) { - blocks_and_receipts.push((block, receipts)); - } - - if current_number == Zero::zero() { - break - } else { - current_number = current_number.saturating_sub(One::one()); - } - } - } - - for (block, receipts) in blocks_and_receipts { - let mut block_log_index: u32 = 0; - for (index, receipt) in receipts.iter().enumerate() { - let logs = receipt.logs.clone(); - let mut transaction_log_index: u32 = 0; - let transaction = &block.transactions[index as usize]; - let transaction_hash = H256::from_slice( - Keccak256::digest(&rlp::encode(transaction)).as_slice() - ); - for log in logs { - let mut add: bool = false; - if let ( - Some(VariadicValue::Single(address)), - Some(VariadicValue::Multiple(topics)) - ) = ( - filter.address.clone(), - filter.topics.clone(), - ) { - if address == log.address && log.topics.starts_with(&topics) { - add = true; - } - } else if let Some(VariadicValue::Single(address)) = filter.address { - if address == log.address { - add = true; - } - } else if let Some(VariadicValue::Multiple(topics)) = &filter.topics { - if log.topics.starts_with(&topics) { - add = true; - } - } - if add { - ret.push(Log { - address: log.address.clone(), - topics: log.topics.clone(), - data: Bytes(log.data.clone()), - block_hash: Some(H256::from_slice( - Keccak256::digest(&rlp::encode(&block.header)).as_slice() - )), - block_number: Some(block.header.number.clone()), - transaction_hash: Some(transaction_hash), - transaction_index: Some(U256::from(index)), - log_index: Some(U256::from(block_log_index)), - transaction_log_index: Some(U256::from(transaction_log_index)), - removed: false, - }); - } - transaction_log_index += 1; - block_log_index += 1; - } - } - } - - Ok(ret) - } - - fn work(&self) -> Result { - Ok(Work { - pow_hash: H256::default(), - seed_hash: H256::default(), - target: H256::default(), - number: None, - }) - } - - fn submit_work(&self, _: H64, _: H256, _: H256) -> Result { - Ok(false) - } - - fn submit_hashrate(&self, _: U256, _: H256) -> Result { - Ok(false) - } -} - -pub struct NetApi { - select_chain: SC, - client: Arc, - _marker: PhantomData<(B, BE)>, -} - -impl NetApi { - pub fn new( - client: Arc, - select_chain: SC, - ) -> Self { - Self { - client: client, - select_chain: select_chain, - _marker: PhantomData, - } - } -} - -impl NetApiT for NetApi where - C: ProvideRuntimeApi + StorageProvider + AuxStore, - C::Api: EthereumRuntimeRPCApi, - BE: Backend + 'static, - BE::State: StateBackend, - C: Send + Sync + 'static, - SC: SelectChain + Clone + 'static, - B: BlockT + Send + Sync + 'static, -{ - fn is_listening(&self) -> Result { - Ok(true) - } - - fn peer_count(&self) -> Result { - Ok("0".to_string()) - } - - fn version(&self) -> Result { - let header = self.select_chain.best_chain() - .map_err(|_| internal_err("fetch header failed"))?; - Ok(self.client.runtime_api().chain_id(&BlockId::Hash(header.hash())) - .map_err(|_| internal_err("fetch runtime chain id failed"))?.to_string()) - } -} diff --git a/template/node/Cargo.toml b/template/node/Cargo.toml index 07e5dfb28f..b958e046ba 100644 --- a/template/node/Cargo.toml +++ b/template/node/Cargo.toml @@ -16,7 +16,8 @@ targets = ["x86_64-unknown-linux-gnu"] futures = "0.3.4" log = "0.4.8" structopt = "0.3.8" -jsonrpc-core = "14.0.3" +jsonrpc-core = "15.0.0" +jsonrpc-pubsub = "15.0.0" sp-api = { version = "2.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-blockchain = { version = "2.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "frontier" } diff --git a/template/node/src/rpc.rs b/template/node/src/rpc.rs index 929a733f67..414d742afd 100644 --- a/template/node/src/rpc.rs +++ b/template/node/src/rpc.rs @@ -26,9 +26,15 @@ use sp_transaction_pool::TransactionPool; use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; use sp_consensus::SelectChain; use sc_rpc_api::DenyUnsafe; -use sc_client_api::backend::{StorageProvider, Backend, StateBackend, AuxStore}; +use sc_client_api::{ + backend::{StorageProvider, Backend, StateBackend, AuxStore}, + client::BlockchainEvents +}; +use sc_rpc::SubscriptionTaskExecutor; use sp_runtime::traits::BlakeTwo256; use sp_block_builder::BlockBuilder; +use sc_network::NetworkService; +use jsonrpc_pubsub::manager::SubscriptionManager; /// Light client extra dependencies. pub struct LightDeps { @@ -54,17 +60,21 @@ pub struct FullDeps { pub deny_unsafe: DenyUnsafe, /// The Node authority flag pub is_authority: bool, + /// Network service + pub network: Arc>, /// Manual seal command sink pub command_sink: Option>>, } /// Instantiate all Full RPC extensions. -pub fn create_full( +pub fn create_full( deps: FullDeps, -) -> jsonrpc_core::IoHandler where + subscription_task_executor: SubscriptionTaskExecutor +) -> jsonrpc_core::IoHandler where BE: Backend + 'static, BE::State: StateBackend, C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: BlockchainEvents, C: HeaderBackend + HeaderMetadata + 'static, C: Send + Sync + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, @@ -73,12 +83,11 @@ pub fn create_full( C::Api: frontier_rpc_primitives::EthereumRuntimeRPCApi, ::Error: fmt::Debug, P: TransactionPool + 'static, - M: jsonrpc_core::Metadata + Default, SC: SelectChain +'static, { use substrate_frame_rpc_system::{FullSystem, SystemApi}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; - use frontier_rpc::{EthApi, EthApiServer, NetApi, NetApiServer}; + use frontier_rpc::{EthApi, EthApiServer, NetApi, NetApiServer, EthPubSubApi, EthPubSubApiServer}; let mut io = jsonrpc_core::IoHandler::default(); let FullDeps { @@ -87,6 +96,7 @@ pub fn create_full( select_chain, deny_unsafe, is_authority, + network, command_sink } = deps; @@ -112,6 +122,15 @@ pub fn create_full( select_chain.clone(), )) ); + io.extend_with( + EthPubSubApiServer::to_delegate(EthPubSubApi::new( + pool.clone(), + client.clone(), + select_chain.clone(), + network.clone(), + SubscriptionManager::new(Arc::new(subscription_task_executor)), + )) + ); match command_sink { Some(command_sink) => { diff --git a/template/node/src/service.rs b/template/node/src/service.rs index 5bc361d11c..5acee24aa1 100644 --- a/template/node/src/service.rs +++ b/template/node/src/service.rs @@ -177,11 +177,13 @@ pub fn new_full(config: Configuration, manual_seal: bool) -> Result Result>::IdentificationTuple; type HandleEquivocation = (); + + type WeightInfo = (); } parameter_types! { @@ -246,9 +248,13 @@ impl pallet_timestamp::Trait for Runtime { parameter_types! { pub const ExistentialDeposit: u128 = 500; + // For weight estimation, we assume that the most locks on an individual account will be 50. + // This number may need to be adjusted in the future if this assumption no longer holds true. + pub const MaxLocks: u32 = 50; } impl pallet_balances::Trait for Runtime { + type MaxLocks = MaxLocks; /// The type for recording an account's balance. type Balance = Balance; /// The ubiquitous event type. @@ -519,7 +525,7 @@ impl_runtime_apis! { nonce, false, ) - .map(|(_, ret, gas)| (ret, gas)) + .map(|(_, ret, gas, _)| (ret, gas)) .map_err(|err| err.into()), frame_ethereum::TransactionAction::Create => EVM::execute_create( @@ -531,7 +537,7 @@ impl_runtime_apis! { nonce, false, ) - .map(|(_, _, gas)| (vec![], gas)) + .map(|(_, _, gas, _)| (vec![], gas)) .map_err(|err| err.into()), } } diff --git a/ts-tests/tests/test-block.ts b/ts-tests/tests/test-block.ts index 4251122ab8..e92b722f57 100644 --- a/ts-tests/tests/test-block.ts +++ b/ts-tests/tests/test-block.ts @@ -117,7 +117,7 @@ describeWithFrontier("Frontier RPC (Block)", `simple-specs.json`, (context) => { expect(block).not.null; }); - it("should include previous block hash as parent", async function () { + it.skip("should include previous block hash as parent", async function () { this.timeout(15000); await createAndFinalizeBlock(context.web3); const block = await context.web3.eth.getBlock("latest"); From ec5d86b575658d25ed20a28aec57e691e02f4ed9 Mon Sep 17 00:00:00 2001 From: tgmichel Date: Mon, 28 Sep 2020 13:34:46 +0200 Subject: [PATCH 11/12] Use HeaderBackend instead SelectChain --- Cargo.lock | 1 - rpc/Cargo.toml | 1 - rpc/src/eth.rs | 100 ++++++++++------------------------- rpc/src/eth_pubsub.rs | 34 +++++------- template/node/src/rpc.rs | 16 ++---- template/node/src/service.rs | 2 - 6 files changed, 46 insertions(+), 108 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40ad2af830..9530792689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1472,7 +1472,6 @@ dependencies = [ "sha3 0.8.2", "sp-api", "sp-blockchain", - "sp-consensus", "sp-io", "sp-runtime", "sp-storage", diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 12a46df934..56e4a74069 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -19,7 +19,6 @@ frontier-rpc-primitives = { path = "primitives" } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-api = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } -sp-consensus = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-transaction-pool = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-storage = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } sp-blockchain = { git = "https://github.com/paritytech/substrate.git", branch = "frontier" } diff --git a/rpc/src/eth.rs b/rpc/src/eth.rs index 3a53850fe8..d02e354308 100644 --- a/rpc/src/eth.rs +++ b/rpc/src/eth.rs @@ -20,10 +20,9 @@ use ethereum::{Block as EthereumBlock, Transaction as EthereumTransaction}; use ethereum_types::{H160, H256, H64, U256, U64, H512}; use jsonrpc_core::{BoxFuture, Result, futures::future::{self, Future}}; use futures::future::TryFutureExt; -use sp_runtime::traits::{Block as BlockT, Header as _, UniqueSaturatedInto, Zero, One, Saturating}; +use sp_runtime::traits::{Block as BlockT, UniqueSaturatedInto, Zero, One, Saturating}; use sp_runtime::transaction_validity::TransactionSource; use sp_api::{ProvideRuntimeApi, BlockId}; -use sp_consensus::SelectChain; use sp_transaction_pool::TransactionPool; use sc_client_api::backend::{StorageProvider, Backend, StateBackend, AuxStore}; use sha3::{Keccak256, Digest}; @@ -39,24 +38,22 @@ use crate::internal_err; pub use frontier_rpc_core::{EthApiServer, NetApiServer}; -pub struct EthApi { +pub struct EthApi { pool: Arc

, client: Arc, - select_chain: SC, convert_transaction: CT, is_authority: bool, _marker: PhantomData<(B, BE)>, } -impl EthApi { +impl EthApi { pub fn new( client: Arc, - select_chain: SC, pool: Arc

, convert_transaction: CT, is_authority: bool ) -> Self { - Self { client, select_chain, pool, convert_transaction, is_authority, _marker: PhantomData } + Self { client, pool, convert_transaction, is_authority, _marker: PhantomData } } } @@ -171,7 +168,7 @@ fn transaction_build( } } -impl EthApi where +impl EthApi where C: ProvideRuntimeApi + StorageProvider + AuxStore, C: HeaderBackend + HeaderMetadata + 'static, C::Api: EthereumRuntimeRPCApi, @@ -179,7 +176,6 @@ impl EthApi where BE::State: StateBackend, B: BlockT + Send + Sync + 'static, C: Send + Sync + 'static, - SC: SelectChain + Clone + 'static, P: TransactionPool + Send + Sync + 'static, CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, { @@ -193,9 +189,7 @@ impl EthApi where }, BlockNumber::Latest => { Some(BlockId::Hash( - self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? - .hash() + self.client.info().best_hash )) }, BlockNumber::Earliest => { @@ -233,7 +227,7 @@ impl EthApi where } } -impl EthApiT for EthApi where +impl EthApiT for EthApi where C: ProvideRuntimeApi + StorageProvider + AuxStore, C: HeaderBackend + HeaderMetadata + 'static, C::Api: EthereumRuntimeRPCApi, @@ -241,7 +235,6 @@ impl EthApiT for EthApi where BE::State: StateBackend, B: BlockT + Send + Sync + 'static, C: Send + Sync + 'static, - SC: SelectChain + Clone + 'static, P: TransactionPool + Send + Sync + 'static, CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, { @@ -250,12 +243,7 @@ impl EthApiT for EthApi where } fn syncing(&self) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - - let block_number = U256::from(header.number().clone().unique_saturated_into()); + let block_number = U256::from(self.client.info().best_number.clone().unique_saturated_into()); Ok(SyncStatus::Info(SyncInfo { starting_block: U256::zero(), @@ -271,14 +259,12 @@ impl EthApiT for EthApi where } fn author(&self) -> Result { - let header = self.select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + let hash = self.client.info().best_hash; Ok( self.client .runtime_api() - .author(&BlockId::Hash(header.hash())) + .author(&BlockId::Hash(hash)) .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))?.into() ) } @@ -288,21 +274,17 @@ impl EthApiT for EthApi where } fn chain_id(&self) -> Result> { - let header = self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - Ok(Some(self.client.runtime_api().chain_id(&BlockId::Hash(header.hash())) + let hash = self.client.info().best_hash; + Ok(Some(self.client.runtime_api().chain_id(&BlockId::Hash(hash)) .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))?.into())) } fn gas_price(&self) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + let hash = self.client.info().best_hash; Ok( self.client .runtime_api() - .gas_price(&BlockId::Hash(header.hash())) + .gas_price(&BlockId::Hash(hash)) .map_err(|err| internal_err(format!("fetch runtime chain id failed: {:?}", err)))? .into(), ) @@ -313,11 +295,7 @@ impl EthApiT for EthApi where } fn block_number(&self) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; - Ok(U256::from(header.number().clone().unique_saturated_into())) + Ok(U256::from(self.client.info().best_number.clone().unique_saturated_into())) } fn balance(&self, address: H160, number: Option) -> Result { @@ -483,17 +461,11 @@ impl EthApiT for EthApi where let transaction_hash = H256::from_slice( Keccak256::digest(&rlp::encode(&transaction)).as_slice() ); - let header = match self.select_chain.best_chain() { - Ok(header) => header, - Err(_) => return Box::new( - future::result(Err(internal_err("fetch header failed"))) - ), - }; - let best_block_hash = header.hash(); + let hash = self.client.info().best_hash; Box::new( self.pool .submit_one( - &BlockId::hash(best_block_hash), + &BlockId::hash(hash), TransactionSource::Local, self.convert_transaction.convert_transaction(transaction), ) @@ -504,10 +476,7 @@ impl EthApiT for EthApi where } fn call(&self, request: CallRequest, _: Option) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + let hash = self.client.info().best_hash; let from = request.from.unwrap_or_default(); let to = request.to.unwrap_or_default(); @@ -519,7 +488,7 @@ impl EthApiT for EthApi where let (ret, _) = self.client.runtime_api() .call( - &BlockId::Hash(header.hash()), + &BlockId::Hash(hash), from, data, value, @@ -535,10 +504,7 @@ impl EthApiT for EthApi where } fn estimate_gas(&self, request: CallRequest, _: Option) -> Result { - let header = self - .select_chain - .best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))?; + let hash = self.client.info().best_hash; let from = request.from.unwrap_or_default(); let gas_price = request.gas_price; @@ -549,7 +515,7 @@ impl EthApiT for EthApi where let (_, used_gas) = self.client.runtime_api() .call( - &BlockId::Hash(header.hash()), + &BlockId::Hash(hash), from, data, value, @@ -778,18 +744,14 @@ impl EthApiT for EthApi where .and_then(|v| v.to_min_block_num()) .map(|s| s.unique_saturated_into()) .unwrap_or( - *self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? - .number() + self.client.info().best_number ); let from_number = filter.from_block .and_then(|v| v.to_min_block_num()) .map(|s| s.unique_saturated_into()) .unwrap_or( - *self.select_chain.best_chain() - .map_err(|err| internal_err(format!("fetch header failed: {:?}", err)))? - .number() + self.client.info().best_number ); while current_number >= from_number { @@ -886,32 +848,29 @@ impl EthApiT for EthApi where } } -pub struct NetApi { - select_chain: SC, +pub struct NetApi { client: Arc, _marker: PhantomData<(B, BE)>, } -impl NetApi { +impl NetApi { pub fn new( client: Arc, - select_chain: SC, ) -> Self { Self { client: client, - select_chain: select_chain, _marker: PhantomData, } } } -impl NetApiT for NetApi where +impl NetApiT for NetApi where C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, C::Api: EthereumRuntimeRPCApi, BE: Backend + 'static, BE::State: StateBackend, C: Send + Sync + 'static, - SC: SelectChain + Clone + 'static, B: BlockT + Send + Sync + 'static, { fn is_listening(&self) -> Result { @@ -923,9 +882,8 @@ impl NetApiT for NetApi where } fn version(&self) -> Result { - let header = self.select_chain.best_chain() - .map_err(|_| internal_err("fetch header failed"))?; - Ok(self.client.runtime_api().chain_id(&BlockId::Hash(header.hash())) + let hash = self.client.info().best_hash; + Ok(self.client.runtime_api().chain_id(&BlockId::Hash(hash)) .map_err(|_| internal_err("fetch runtime chain id failed"))?.to_string()) } } diff --git a/rpc/src/eth_pubsub.rs b/rpc/src/eth_pubsub.rs index a9701772e9..80d8b584b5 100644 --- a/rpc/src/eth_pubsub.rs +++ b/rpc/src/eth_pubsub.rs @@ -1,12 +1,12 @@ use std::{marker::PhantomData, sync::Arc}; use std::collections::BTreeMap; use sp_runtime::traits::{ - Block as BlockT, Header as _, BlakeTwo256, + Block as BlockT, BlakeTwo256, UniqueSaturatedInto }; use sp_transaction_pool::TransactionPool; use sp_api::{ProvideRuntimeApi, BlockId}; -use sp_blockchain::HeaderBackend; +use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; use sp_storage::{StorageKey, StorageData}; use sp_io::hashing::twox_128; use sc_client_api::{ @@ -14,7 +14,6 @@ use sc_client_api::{ client::BlockchainEvents }; use sc_rpc::Metadata; -use sp_consensus::SelectChain; use log::warn; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; @@ -36,44 +35,37 @@ use frontier_rpc_primitives::{EthereumRuntimeRPCApi, TransactionStatus}; use sc_network::{NetworkService, ExHashT}; use crate::internal_err; -pub struct EthPubSubApi { +pub struct EthPubSubApi { _pool: Arc

, client: Arc, - select_chain: SC, network: Arc>, subscriptions: SubscriptionManager, _marker: PhantomData<(B, BE)>, } -impl EthPubSubApi { +impl EthPubSubApi { pub fn new( _pool: Arc

, client: Arc, - select_chain: SC, network: Arc>, subscriptions: SubscriptionManager, ) -> Self { - Self { _pool, client, select_chain, network, subscriptions, _marker: PhantomData } + Self { _pool, client, network, subscriptions, _marker: PhantomData } } } -impl EthPubSubApi where +impl EthPubSubApi where B: BlockT + Send + Sync + 'static, P: TransactionPool + Send + Sync + 'static, C: ProvideRuntimeApi + StorageProvider + - BlockchainEvents + HeaderBackend + AuxStore, + BlockchainEvents + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, C::Api: EthereumRuntimeRPCApi, C: Send + Sync + 'static, BE: Backend + 'static, BE::State: StateBackend, - SC: SelectChain + Clone + 'static, { fn native_block_number(&self, number: Option) -> JsonRpcResult> { - let header = self - .select_chain - .best_chain() - .map_err(|_| internal_err("fetch header failed"))?; - let mut native_number: Option = None; if let Some(number) = number { @@ -93,7 +85,7 @@ impl EthPubSubApi where }, BlockNumber::Latest => { native_number = Some( - header.number().clone().unique_saturated_into() as u32 + self.client.info().best_number.clone().unique_saturated_into() as u32 ); }, BlockNumber::Earliest => { @@ -105,7 +97,7 @@ impl EthPubSubApi where }; } else { native_number = Some( - header.number().clone().unique_saturated_into() as u32 + self.client.info().best_number.clone().unique_saturated_into() as u32 ); } Ok(native_number) @@ -377,17 +369,17 @@ macro_rules! stream_build { }}; } -impl EthPubSubApiT for EthPubSubApi +impl EthPubSubApiT for EthPubSubApi where B: BlockT + Send + Sync + 'static, P: TransactionPool + Send + Sync + 'static, C: ProvideRuntimeApi + StorageProvider + - BlockchainEvents + HeaderBackend + AuxStore, + BlockchainEvents + AuxStore, + C: HeaderBackend + HeaderMetadata + 'static, C: Send + Sync + 'static, C::Api: EthereumRuntimeRPCApi, BE: Backend + 'static, BE::State: StateBackend, - SC: SelectChain + Clone + 'static, { type Metadata = Metadata; fn subscribe( diff --git a/template/node/src/rpc.rs b/template/node/src/rpc.rs index 414d742afd..74ce5b5935 100644 --- a/template/node/src/rpc.rs +++ b/template/node/src/rpc.rs @@ -24,7 +24,6 @@ use frontier_template_runtime::{Hash, AccountId, Index, opaque::Block, Balance}; use sp_api::ProvideRuntimeApi; use sp_transaction_pool::TransactionPool; use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; -use sp_consensus::SelectChain; use sc_rpc_api::DenyUnsafe; use sc_client_api::{ backend::{StorageProvider, Backend, StateBackend, AuxStore}, @@ -49,13 +48,11 @@ pub struct LightDeps { } /// Full client dependencies. -pub struct FullDeps { +pub struct FullDeps { /// The client instance to use. pub client: Arc, /// Transaction pool instance. pub pool: Arc

, - /// The SelectChain Strategy - pub select_chain: SC, /// Whether to deny unsafe calls pub deny_unsafe: DenyUnsafe, /// The Node authority flag @@ -67,15 +64,15 @@ pub struct FullDeps { } /// Instantiate all Full RPC extensions. -pub fn create_full( - deps: FullDeps, +pub fn create_full( + deps: FullDeps, subscription_task_executor: SubscriptionTaskExecutor ) -> jsonrpc_core::IoHandler where BE: Backend + 'static, BE::State: StateBackend, C: ProvideRuntimeApi + StorageProvider + AuxStore, C: BlockchainEvents, - C: HeaderBackend + HeaderMetadata + 'static, + C: HeaderBackend + HeaderMetadata, C: Send + Sync + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: BlockBuilder, @@ -83,7 +80,6 @@ pub fn create_full( C::Api: frontier_rpc_primitives::EthereumRuntimeRPCApi, ::Error: fmt::Debug, P: TransactionPool + 'static, - SC: SelectChain +'static, { use substrate_frame_rpc_system::{FullSystem, SystemApi}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; @@ -93,7 +89,6 @@ pub fn create_full( let FullDeps { client, pool, - select_chain, deny_unsafe, is_authority, network, @@ -109,7 +104,6 @@ pub fn create_full( io.extend_with( EthApiServer::to_delegate(EthApi::new( client.clone(), - select_chain.clone(), pool.clone(), frontier_template_runtime::TransactionConverter, is_authority, @@ -119,14 +113,12 @@ pub fn create_full( io.extend_with( NetApiServer::to_delegate(NetApi::new( client.clone(), - select_chain.clone(), )) ); io.extend_with( EthPubSubApiServer::to_delegate(EthPubSubApi::new( pool.clone(), client.clone(), - select_chain.clone(), network.clone(), SubscriptionManager::new(Arc::new(subscription_task_executor)), )) diff --git a/template/node/src/service.rs b/template/node/src/service.rs index 5acee24aa1..6997440b8e 100644 --- a/template/node/src/service.rs +++ b/template/node/src/service.rs @@ -181,14 +181,12 @@ pub fn new_full(config: Configuration, manual_seal: bool) -> Result Date: Mon, 28 Sep 2020 16:25:43 +0200 Subject: [PATCH 12/12] Temporary patch for load_block_hash --- rpc/src/eth.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/rpc/src/eth.rs b/rpc/src/eth.rs index d02e354308..040822dae9 100644 --- a/rpc/src/eth.rs +++ b/rpc/src/eth.rs @@ -20,7 +20,7 @@ use ethereum::{Block as EthereumBlock, Transaction as EthereumTransaction}; use ethereum_types::{H160, H256, H64, U256, U64, H512}; use jsonrpc_core::{BoxFuture, Result, futures::future::{self, Future}}; use futures::future::TryFutureExt; -use sp_runtime::traits::{Block as BlockT, UniqueSaturatedInto, Zero, One, Saturating}; +use sp_runtime::traits::{Block as BlockT, Header as _, UniqueSaturatedInto, Zero, One, Saturating}; use sp_runtime::transaction_validity::TransactionSource; use sp_api::{ProvideRuntimeApi, BlockId}; use sp_transaction_pool::TransactionPool; @@ -225,6 +225,16 @@ impl EthApi where } Ok(None) } + + fn headers(&self, id: &BlockId) -> (u64,u64) { + let best_number: u64 = UniqueSaturatedInto::::unique_saturated_into( + self.client.info().best_number + ); + let header_number: u64 = UniqueSaturatedInto::::unique_saturated_into( + *self.client.header(id.clone()).unwrap().unwrap().number() + ); + (best_number, header_number) + } } impl EthApiT for EthApi where @@ -331,6 +341,10 @@ impl EthApiT for EthApi where Some(hash) => hash, _ => return Ok(None), }; + let (best_number, header_number) = self.headers(&id); + if header_number > best_number { + return Ok(None); + } let block = self.client.runtime_api().current_block(&id) .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; @@ -403,6 +417,10 @@ impl EthApiT for EthApi where Some(hash) => hash, _ => return Ok(None), }; + let (best_number, header_number) = self.headers(&id); + if header_number > best_number { + return Ok(None); + } let block = self.client.runtime_api() .current_block(&id) @@ -548,6 +566,10 @@ impl EthApiT for EthApi where Some(hash) => hash, _ => return Ok(None), }; + let (best_number, header_number) = self.headers(&id); + if header_number > best_number { + return Ok(None); + } let block = self.client.runtime_api().current_block(&id) .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; @@ -577,6 +599,10 @@ impl EthApiT for EthApi where Some(hash) => hash, _ => return Ok(None), }; + let (best_number, header_number) = self.headers(&id); + if header_number > best_number { + return Ok(None); + } let index = index.value(); let block = self.client.runtime_api().current_block(&id) @@ -639,6 +665,10 @@ impl EthApiT for EthApi where Some(hash) => hash, _ => return Ok(None), }; + let (best_number, header_number) = self.headers(&id); + if header_number > best_number { + return Ok(None); + } let block = self.client.runtime_api().current_block(&id) .map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?; @@ -729,6 +759,10 @@ impl EthApiT for EthApi where Some(hash) => hash, _ => return Ok(Vec::new()), }; + let (best_number, header_number) = self.headers(&id); + if header_number > best_number { + return Ok(Vec::new()); + } let block = self.client.runtime_api() .current_block(&id)