diff --git a/Cargo.lock b/Cargo.lock index 6ad92da6958d08a18206b3d2b3e8287f36c469c7..d33bf6464a422ebfa042025479ad55aa289afb17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8187,6 +8187,19 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "git2" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fda788993cc341f69012feba8bf45c0ba4f3291fcc08e214b4d5a7332d88aff" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "glob" version = "0.3.1" @@ -8729,7 +8742,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -9833,6 +9846,18 @@ dependencies = [ "once_cell", ] +[[package]] +name = "libgit2-sys" +version = "0.18.0+1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1a117465e7e1597e8febea8bb0c410f1c7fb93b1e1cddf34363f8390367ffec" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + [[package]] name = "libloading" version = "0.7.4" @@ -14955,6 +14980,7 @@ dependencies = [ "env_logger 0.11.3", "ethabi", "futures", + "git2", "hex", "jsonrpsee", "log", @@ -16475,7 +16501,7 @@ checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" dependencies = [ "bitcoin_hashes 0.13.0", "rand", - "rand_core 0.5.1", + "rand_core 0.6.4", "serde", "unicode-normalization", ] @@ -20737,7 +20763,7 @@ checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.12.1", + "itertools 0.13.0", "log", "multimap", "once_cell", @@ -20783,7 +20809,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.13.0", "proc-macro2 1.0.93", "quote 1.0.38", "syn 2.0.98", diff --git a/prdoc/pr_7580.prdoc b/prdoc/pr_7580.prdoc new file mode 100644 index 0000000000000000000000000000000000000000..ba041355506e485d3b1543b8918320d07a7e9f6b --- /dev/null +++ b/prdoc/pr_7580.prdoc @@ -0,0 +1,10 @@ +title: implement web3_clientVersion +doc: +- audience: Runtime Dev + description: |- + Implements the `web3_clientVersion` method. This is a common requirement for external Ethereum libraries when querying a client. + + Reference issue with more details: https://github.com/paritytech/contract-issues/issues/26. +crates: +- name: pallet-revive-eth-rpc + bump: minor diff --git a/substrate/frame/revive/rpc/Cargo.toml b/substrate/frame/revive/rpc/Cargo.toml index b207a6041b9b6cf3230a713270c48d23eb5b4b8b..33d447e67a20369f2a1f18623a8a879bf654fce1 100644 --- a/substrate/frame/revive/rpc/Cargo.toml +++ b/substrate/frame/revive/rpc/Cargo.toml @@ -75,3 +75,6 @@ pretty_assertions = { workspace = true } static_init = { workspace = true } substrate-cli-test-utils = { workspace = true } subxt-signer = { workspace = true, features = ["unstable-eth"] } + +[build-dependencies] +git2 = { version = "0.20.0", default-features = false } diff --git a/substrate/frame/revive/rpc/build.rs b/substrate/frame/revive/rpc/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..d2ea601211a00a6f0b44e5c4dc272f592cdb0a16 --- /dev/null +++ b/substrate/frame/revive/rpc/build.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +use std::process::Command; + +/// Get the current branch and commit hash. +fn main() { + let output = Command::new("rustc") + .arg("--version") + .output() + .expect("cannot get the current rustc version"); + // Exports the default rustc --version output: + // e.g. rustc 1.83.0 (90b35a623 2024-11-26) + // into the usual Ethereum web3_clientVersion format + // e.g. rustc1.83.0 + let rustc_version = String::from_utf8_lossy(&output.stdout) + .split_whitespace() + .take(2) + .collect::<Vec<_>>() + .join(""); + let target = std::env::var("TARGET").unwrap_or_else(|_| "unknown".to_string()); + + let repo = git2::Repository::open("../../../..").expect("should be a repository"); + let head = repo.head().expect("should have head"); + let commit = head.peel_to_commit().expect("should have commit"); + let branch = head.shorthand().unwrap_or("unknown").to_string(); + let id = &commit.id().to_string()[..7]; + println!("cargo:rustc-env=GIT_REVISION={branch}-{id}"); + println!("cargo:rustc-env=RUSTC_VERSION={rustc_version}"); + println!("cargo:rustc-env=TARGET={target}"); +} diff --git a/substrate/frame/revive/rpc/src/apis/execution_apis.rs b/substrate/frame/revive/rpc/src/apis/execution_apis.rs index f55209fce585606a026430619ec9453c3163c234..b867e8acf30f06f764f4aea38c94048baa74ef9b 100644 --- a/substrate/frame/revive/rpc/src/apis/execution_apis.rs +++ b/substrate/frame/revive/rpc/src/apis/execution_apis.rs @@ -166,4 +166,8 @@ pub trait EthRpc { /// The string value of current network id #[method(name = "net_version")] async fn net_version(&self) -> RpcResult<String>; + + /// The string value of the current client version + #[method(name = "web3_clientVersion")] + async fn web3_client_version(&self) -> RpcResult<String>; } diff --git a/substrate/frame/revive/rpc/src/lib.rs b/substrate/frame/revive/rpc/src/lib.rs index 8d6797722d4f2bf4eb954832692ca9ff11b1d62c..31af6a5bbb0debf9a3941e579971e70c46068c78 100644 --- a/substrate/frame/revive/rpc/src/lib.rs +++ b/substrate/frame/revive/rpc/src/lib.rs @@ -352,4 +352,11 @@ impl EthRpcServer for EthRpcServerImpl { let nonce = self.client.nonce(address, block).await?; Ok(nonce) } + + async fn web3_client_version(&self) -> RpcResult<String> { + let git_revision = env!("GIT_REVISION"); + let rustc_version = env!("RUSTC_VERSION"); + let target = env!("TARGET"); + Ok(format!("eth-rpc/{git_revision}/{target}/{rustc_version}")) + } }