From 75ca3f94c19496aab6ea2cfea0cf01039e615b91 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Mon, 7 Oct 2024 15:14:50 +0200 Subject: [PATCH 01/37] Add pallet-revive Ethereum JSON-RPC Depends on #5866 --- Cargo.lock | 152 +++- Cargo.toml | 2 + substrate/frame/revive/rpc/Cargo.toml | 67 ++ substrate/frame/revive/rpc/Makefile | 30 + substrate/frame/revive/rpc/examples/deploy.rs | 58 ++ .../frame/revive/rpc/examples/dummy.polkavm | Bin 0 -> 142 bytes .../frame/revive/rpc/examples/extrinsic.rs | 48 ++ .../revive/rpc/examples/rpc-playground.rs | 29 + .../frame/revive/rpc/examples/transfer.rs | 31 + substrate/frame/revive/rpc/kitchensink.scale | Bin 0 -> 651254 bytes substrate/frame/revive/rpc/metadata.scale | Bin 0 -> 57102 bytes substrate/frame/revive/rpc/src/client.rs | 741 ++++++++++++++++++ substrate/frame/revive/rpc/src/example.rs | 114 +++ substrate/frame/revive/rpc/src/lib.rs | 305 +++++++ substrate/frame/revive/rpc/src/main.rs | 128 +++ .../frame/revive/rpc/src/rpc_methods_gen.rs | 152 ++++ .../frame/revive/rpc/src/subxt_client.rs | 45 ++ 17 files changed, 1901 insertions(+), 1 deletion(-) create mode 100644 substrate/frame/revive/rpc/Cargo.toml create mode 100644 substrate/frame/revive/rpc/Makefile create mode 100644 substrate/frame/revive/rpc/examples/deploy.rs create mode 100644 substrate/frame/revive/rpc/examples/dummy.polkavm create mode 100644 substrate/frame/revive/rpc/examples/extrinsic.rs create mode 100644 substrate/frame/revive/rpc/examples/rpc-playground.rs create mode 100644 substrate/frame/revive/rpc/examples/transfer.rs create mode 100644 substrate/frame/revive/rpc/kitchensink.scale create mode 100644 substrate/frame/revive/rpc/metadata.scale create mode 100644 substrate/frame/revive/rpc/src/client.rs create mode 100644 substrate/frame/revive/rpc/src/example.rs create mode 100644 substrate/frame/revive/rpc/src/lib.rs create mode 100644 substrate/frame/revive/rpc/src/main.rs create mode 100644 substrate/frame/revive/rpc/src/rpc_methods_gen.rs create mode 100644 substrate/frame/revive/rpc/src/subxt_client.rs diff --git a/Cargo.lock b/Cargo.lock index 93e98a329e76..bb89ecdfff11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,6 +119,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.16" @@ -1145,6 +1160,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-compression" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "zstd 0.13.0", + "zstd-safe 7.0.0", +] + [[package]] name = "async-executor" version = "1.5.1" @@ -2574,6 +2605,27 @@ dependencies = [ "tuplex", ] +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bs58" version = "0.5.1" @@ -7406,6 +7458,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +[[package]] +name = "http-range-header" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" + [[package]] name = "httparse" version = "1.8.0" @@ -7885,6 +7943,16 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +[[package]] +name = "iri-string" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bd7eced44cfe2cebc674adb2a7124a754a4b5269288d22e9f39f8fada3562d" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-terminal" version = "0.4.9" @@ -9667,6 +9735,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -12441,6 +12519,36 @@ dependencies = [ "subxt-signer", ] +[[package]] +name = "pallet-revive-eth-rpc" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.5.13", + "env_logger 0.11.3", + "futures", + "hex", + "hex-literal", + "hyper 1.3.1", + "jsonrpsee 0.24.3", + "log", + "pallet-revive", + "parity-scale-codec", + "scale-info", + "secp256k1", + "serde_json", + "sp-core 28.0.0", + "sp-runtime 31.0.1", + "sp-weights 27.0.0", + "subxt", + "subxt-signer", + "thiserror", + "tokio", + "tower", + "tower-http 0.5.2", + "tracing-subscriber 0.3.18", +] + [[package]] name = "pallet-revive-fixtures" version = "0.1.0" @@ -25156,7 +25264,7 @@ dependencies = [ "futures-util", "http 0.2.9", "http-body 0.4.5", - "http-range-header", + "http-range-header 0.3.1", "mime", "pin-project-lite", "tower-layer", @@ -25170,14 +25278,29 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ + "async-compression", + "base64 0.21.7", "bitflags 2.6.0", "bytes", + "futures-core", + "futures-util", "http 1.1.0", "http-body 1.0.0", "http-body-util", + "http-range-header 0.4.1", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding", "pin-project-lite", + "tokio", + "tokio-util", + "tower", "tower-layer", "tower-service", + "tracing", + "uuid", ] [[package]] @@ -25594,6 +25717,15 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -27433,6 +27565,15 @@ dependencies = [ "zstd-safe 6.0.6", ] +[[package]] +name = "zstd" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +dependencies = [ + "zstd-safe 7.0.0", +] + [[package]] name = "zstd-safe" version = "5.0.2+zstd.1.5.2" @@ -27453,6 +27594,15 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.8+zstd.1.5.5" diff --git a/Cargo.toml b/Cargo.toml index fde05e90ca6e..d265f1a586f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -399,6 +399,7 @@ members = [ "substrate/frame/revive/fixtures", "substrate/frame/revive/mock-network", "substrate/frame/revive/proc-macro", + "substrate/frame/revive/rpc", "substrate/frame/revive/uapi", "substrate/frame/root-offences", "substrate/frame/root-testing", @@ -958,6 +959,7 @@ pallet-recovery = { path = "substrate/frame/recovery", default-features = false pallet-referenda = { path = "substrate/frame/referenda", default-features = false } pallet-remark = { default-features = false, path = "substrate/frame/remark" } pallet-revive = { path = "substrate/frame/revive", default-features = false } +pallet-revive-eth-rpc = { path = "substrate/frame/revive/rpc", default-features = false } pallet-revive-fixtures = { path = "substrate/frame/revive/fixtures", default-features = false } pallet-revive-mock-network = { default-features = false, path = "substrate/frame/revive/mock-network" } pallet-revive-proc-macro = { path = "substrate/frame/revive/proc-macro", default-features = false } diff --git a/substrate/frame/revive/rpc/Cargo.toml b/substrate/frame/revive/rpc/Cargo.toml new file mode 100644 index 000000000000..dbb84af54446 --- /dev/null +++ b/substrate/frame/revive/rpc/Cargo.toml @@ -0,0 +1,67 @@ +[package] +name = "pallet-revive-eth-rpc" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true +description = "An Ethereum JSON-RPC server for pallet-revive." + +[[bin]] +name = "eth-rpc" +path = "src/main.rs" + +[[example]] +name = "deploy" +path = "examples/deploy.rs" +required-features = ["example"] + +[[example]] +name = "transfer" +path = "examples/transfer.rs" +required-features = ["example"] + +[[example]] +name = "rpc-playground" +path = "examples/rpc-playground.rs" +required-features = ["example"] + +[[example]] +name = "extrinsic" +path = "examples/extrinsic.rs" +required-features = ["example"] + +[dependencies] +clap = { workspace = true, features = ["derive"] } +anyhow.workspace = true +futures = { workspace = true, features = ["thread-pool"] } +jsonrpsee = { workspace = true, features = ["full"] } +serde_json.workspace = true +thiserror.workspace = true +subxt = { workspace = true, default-features = true, features = ["unstable-reconnecting-rpc-client"] } +tokio = { workspace = true, features = ["full"] } +codec = { workspace = true, features = ["derive"] } +log.workspace = true +tracing-subscriber.workspace = true +pallet-revive = { workspace = true, default-features = true } +sp-core = { workspace = true, default-features = true } +sp-weights = { workspace = true, default-features = true } +sp-runtime = { workspace = true, default-features = true } + +tower.workspace = true +tower-http = { workspace = true, features = ["full"] } +hyper.workspace = true +subxt-signer = { workspace = true, optional = true } +hex = { workspace = true, optional = true } +hex-literal = { workspace = true, optional = true } +scale-info = { workspace = true } +secp256k1 = { workspace = true, optional = true, features = ["recovery"] } +env_logger = { workspace = true } + +[features] +dev = [] +example = ["hex", "hex-literal", "secp256k1", "subxt-signer"] + +[dev-dependencies] +hex-literal.workspace = true diff --git a/substrate/frame/revive/rpc/Makefile b/substrate/frame/revive/rpc/Makefile new file mode 100644 index 000000000000..64db1396a46c --- /dev/null +++ b/substrate/frame/revive/rpc/Makefile @@ -0,0 +1,30 @@ +.PHONY: node +node: + RUST_LOG="error,evm=debug,sc_rpc_server=info,runtime::revive=debug" cargo run -p node -- --dev --consensus instant-seal + +.PHONY: rpc +rpc: + RUST_LOG="info,eth-rpc=debug" cargo run --features dev + +# Generate the metadata file for the runtime +# Make sure your chain is running before running this command +# Usage: make metadata METADATA_FILE=.scale +CHAIN ?= kitchen_sink +.PHONY: metadata +metadata: +ifndef CHAIN + $(error CHAIN is not defined. Please specify it when running make, e.g., make metadata CHAIN=) +endif + @subxt explore --url ws://localhost:9944 pallet Revive constants chainId > /dev/null + subxt metadata --url ws://localhost:9944 -o $(CHAIN).scale + touch src/subxt_client.rs + +SALT ?= 0 +.PHONY: example_deploy +example_deploy: + RUST_LOG=info cargo run --manifest-path rpc/Cargo.toml --features example --example deploy $(SALT) + +.PHONY: example_transfer +example_transfer: + RUST_LOG=info cargo run --manifest-path rpc/Cargo.toml --features example --example transfer + diff --git a/substrate/frame/revive/rpc/examples/deploy.rs b/substrate/frame/revive/rpc/examples/deploy.rs new file mode 100644 index 000000000000..b75964fc424e --- /dev/null +++ b/substrate/frame/revive/rpc/examples/deploy.rs @@ -0,0 +1,58 @@ +use codec::Encode; +use eth_rpc::{example::Account, EthRpcClient, ReceiptInfo}; +use jsonrpsee::http_client::HttpClientBuilder; +use polkadot_sdk::pallet_revive::{ + create1, + evm::{BlockTag, Bytes, U256}, + EthInstantiateInput, +}; + +static DUMMY_BYTES: &[u8] = include_bytes!("./dummy.polkavm"); + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + env_logger::init(); + let account = Account::default(); + let data = vec![]; + let input = EthInstantiateInput { code: DUMMY_BYTES.to_vec(), data: data.clone() }; + + println!("Account address: {:?}", account.address()); + let client = HttpClientBuilder::default().build("http://localhost:9090".to_string())?; + + println!("\n\n=== Deploying contract ===\n\n"); + + let input = input.encode(); + let nonce = client.get_transaction_count(account.address(), BlockTag::Latest.into()).await?; + let hash = account.send_transaction(&client, U256::zero(), input.into(), None).await?; + println!("Deploy Tx hash: {hash:?}"); + + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + let ReceiptInfo { block_number, gas_used, contract_address, .. } = + client.get_transaction_receipt(hash).await?.unwrap(); + println!("Receipt received: "); + println!("Block number: {block_number}"); + println!("Gas used: {gas_used}"); + println!("Contract address: {contract_address:?}"); + + if std::env::var("SKIP_CALL").is_ok() { + return Ok(()) + } + + let contract_address = create1(&account.address(), nonce.try_into().unwrap()); + println!("\n\n=== Calling contract ===\n\n"); + + let hash = account + .send_transaction(&client, U256::zero(), Bytes::default(), Some(contract_address)) + .await?; + + println!("Contract call tx hash: {hash:?}"); + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + + let ReceiptInfo { block_number, gas_used, to, .. } = + client.get_transaction_receipt(hash).await?.unwrap(); + println!("Receipt received: "); + println!("Block number: {block_number}"); + println!("Gas used: {gas_used}"); + println!("To: {to:?}"); + Ok(()) +} diff --git a/substrate/frame/revive/rpc/examples/dummy.polkavm b/substrate/frame/revive/rpc/examples/dummy.polkavm new file mode 100644 index 0000000000000000000000000000000000000000..6dae51890f046a1c4efe5a8d6270c9d8b8755f68 GIT binary patch literal 142 zcmWFt^JQRUWKm(5z`&%OoS2hyZ|%PKAUZxTwJfzLCAA for SrcChainSigner { + fn account_id(&self) -> ::AccountId { + self.0.public_key().into() + } + fn address(&self) -> ::Address { + self.0.public_key().into() + } + + fn sign(&self, signer_payload: &[u8]) -> ::Signature { + MultiSignature::Sr25519(self.0.sign(signer_payload).0.into()) + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = OnlineClient::::new().await?; + + println!("\n\n=== Deploying contract ===\n\n"); + + let tx_payload = subxt_client::tx().revive().instantiate_with_code( + 0u32.into(), + Weight::from_parts(2_000, 2_000).into(), + 10000000u32.into(), + DUMMY_BYTES.to_vec(), + vec![], + None, + ); + + let res = client + .tx() + .sign_and_submit_default_then_watch(&tx_payload, &SrcChainSigner(dev::alice())) + .await? + .wait_for_finalized_success() + .await?; + println!("Transaction finalized: {:?}", res.extrinsic_hash()); + + Ok(()) +} diff --git a/substrate/frame/revive/rpc/examples/rpc-playground.rs b/substrate/frame/revive/rpc/examples/rpc-playground.rs new file mode 100644 index 000000000000..6ada8bbf9405 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/rpc-playground.rs @@ -0,0 +1,29 @@ +use eth_rpc::{example::Account, EthRpcClient}; +use jsonrpsee::http_client::HttpClientBuilder; +use polkadot_sdk::pallet::revive_evm::BlockTag; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let data = hex_literal::hex!("0xf86b800184254ac125947bf369283338e12c90514468aa3868a551ab29298898a7d9b8314c0000808204cba0d82f7414276d8c4925f69c1b1c2507be08973e03ea2cdf5d2cae86610929cbe2a0033f3f7e1dad86b3e2cb466abe41a1658c7247f5ac4cbe237d47564bf990139e"); + let tx = rlp::decode::(&data).unwrap(); + dbg!(tx); + + let account = Account::default(); + println!("Account address: {:?}", account.address()); + + let client = HttpClientBuilder::default().build("http://localhost:9090".to_string())?; + + let block = client.get_block_by_number(BlockTag::Latest.into(), false).await?; + println!("Latest block: {block:#?}"); + + let nonce = client.get_transaction_count(account.address(), BlockTag::Latest.into()).await?; + println!("Account nonce: {nonce:?}"); + + let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?; + println!("Account balance: {balance:?}"); + + Ok(()) +} +//method: eth_sendRawTransaction params: +// ["0xf86b800184254ac125947bf369283338e12c90514468aa3868a551ab29298898a7d9b8314c0000808204cba0d82f7414276d8c4925f69c1b1c2507be08973e03ea2cdf5d2cae86610929cbe2a0033f3f7e1dad86b3e2cb466abe41a1658c7247f5ac4cbe237d47564bf990139e" +// ], diff --git a/substrate/frame/revive/rpc/examples/transfer.rs b/substrate/frame/revive/rpc/examples/transfer.rs new file mode 100644 index 000000000000..f363ca09dc43 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/transfer.rs @@ -0,0 +1,31 @@ +use eth_rpc::{example::Account, EthRpcClient}; +use hex_literal::hex; +use jsonrpsee::http_client::HttpClientBuilder; +use polkadot_sdk::pallet_revive::evm::{BlockTag, Bytes, H160}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let account = Account::default(); + println!("Account address: {:?}", account.address()); + + let client = HttpClientBuilder::default().build("http://localhost:9090".to_string())?; + + let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?; + println!("Account balance: {:?}", balance); + + let to = Some(H160(hex!("c543bb3eF11d96aCA20b3c906cF2C8Daaff925e4"))); + let value = 10_000_000_000_000_000_000u128.into(); // 10 ETH + println!("\n\n=== Transferring ===\n\n"); + + let hash = account.send_transaction(&client, value, Bytes::default(), to).await?; + println!("Transaction hash: {hash:?}"); + + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + let receipt = client.get_transaction_receipt(hash).await; + println!("Receipt: {receipt:?}"); + + let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?; + println!("Account balance: {:?}", balance); + + Ok(()) +} diff --git a/substrate/frame/revive/rpc/kitchensink.scale b/substrate/frame/revive/rpc/kitchensink.scale new file mode 100644 index 0000000000000000000000000000000000000000..f9b520e7d67ad65ffacced036616f7eda0fdebf4 GIT binary patch literal 651254 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 G5Pd@M-notIn^{)N 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

jV`D222cER1+5Gr5w-x^4a4StyJl@v!_!5B|G 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 Q3%ekid;HMSXIt5S0w)E}`2YX_ literal 0 HcmV?d00001 diff --git a/substrate/frame/revive/rpc/metadata.scale b/substrate/frame/revive/rpc/metadata.scale new file mode 100644 index 0000000000000000000000000000000000000000..ffd5662a46e848ca6ce0ef9c6a2d88d03bf18705 GIT binary patch literal 57102 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 literal 0 HcmV?d00001 diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs new file mode 100644 index 000000000000..9e8db2c72f01 --- /dev/null +++ b/substrate/frame/revive/rpc/src/client.rs @@ -0,0 +1,741 @@ +//! The client connects to the source substrate chain +//! and is used by the rpc server to query and send transactions to the substrate chain. + +#![allow(unused_imports, unused_variables)] +use crate::{ + rlp, + subxt_client::{ + revive::calls::types::EthTransact, + runtime_types::{frame_system::EventRecord, revive_runtime::RuntimeEvent}, + }, + TransactionLegacySigned, LOG_TARGET, +}; +use codec::{Decode, Encode}; +use futures::{stream, StreamExt}; +use jsonrpsee::types::{ErrorCode, ErrorObjectOwned}; +use pallet_revive::{ + create1, + evm::{ + Block, BlockNumberOrTag, BlockNumberOrTagOrHash, Bytes256, GenericTransaction, ReceiptInfo, + TransactionSigned, H160, H256, U256, + }, + ContractResult, EthContractResult, EthInstantiateInput, +}; +use sp_runtime::traits::Hash; +use sp_weights::Weight; +use std::{ + collections::{HashMap, VecDeque}, + sync::Arc, + time::Duration, +}; +use subxt::{ + backend::{ + legacy::LegacyRpcMethods, + rpc::{ + reconnecting_rpc_client::{Client as ReconnectingRpcClient, ExponentialBackoff}, + RpcClient, + }, + }, + config::{signed_extensions::CheckNonce, Header}, + error::RpcError, + storage::Storage, + tx::TxClient, + utils::AccountId32, + Config, OnlineClient, +}; +use subxt_client::transaction_payment::events::TransactionFeePaid; +use thiserror::Error; +use tokio::{ + sync::{watch::Sender, RwLock}, + task::JoinSet, +}; + +use crate::subxt_client::{self, system::events::ExtrinsicSuccess, SrcChainConfig}; + +pub mod primitives { + use sp_core::H160; + pub type Hashing = sp_runtime::traits::BlakeTwo256; + pub type AccountId = sp_runtime::AccountId32; + pub type AccountIndex = u32; + pub type MultiAddress = sp_runtime::MultiAddress; +} + +/// The substrate block type. +pub type SubstrateBlock = subxt::blocks::Block>; + +/// The substrate block number type. +pub type SubstrateBlockNumber = <::Header as Header>::Number; + +/// The substrate block hash type. +pub type SubstrateBlockHash = ::Hash; + +/// Type alias for shared data. +pub type Shared = Arc>; + +/// The runtime balance type. +pub type Balance = u128; + +/// The EVM gas price. +/// We use a fixed value for the gas price. +/// This let us calculate the gas estimate for a transaction with the formula: +/// `estimate_gas = substrate_fee / gas_price`. +pub const GAS_PRICE: u128 = 1u128; + +/// The cache maintains a buffer of the last N blocks, +#[derive(Default)] +struct BlockCache { + /// A double-ended queue of the last N blocks. + /// The most recent block is at the back of the queue, and the oldest block is at the front. + buffer: VecDeque>, + + /// A map of blocks by block number. + blocks_by_number: HashMap>, + + /// A map of blocks by block hash. + blocks_by_hash: HashMap>, + + /// A map of receipts by hash. + receipts_by_hash: HashMap, + + /// A map of Signed transaction by hash. + signed_tx_by_hash: HashMap, + + /// A map of receipt hashes by block hash. + tx_hashes_by_block_and_index: HashMap>, +} + +/// The error type for the client. +#[derive(Error, Debug)] +pub enum ClientError { + /// A [`subxt::Error`] wrapper error. + #[error("Subxt error: {0}")] + SubxtError(#[from] subxt::Error), + /// A [`RpcError`] wrapper error. + #[error("RPC error: {0}")] + RpcError(#[from] RpcError), + /// A [`codec::Error`] wrapper error. + #[error("Codec error: {0}")] + CodecError(#[from] codec::Error), + /// The dry run failed. + #[error("Dry run failed")] + DryRunFailed, + /// A decimal conversion failed. + #[error("Conversion failed")] + ConversionFailed, + /// The block hash was not found. + #[error("Hash not found")] + BlockNotFound, + /// The transaction fee could not be found + #[error("TransactionFeePaid event not found")] + TxFeeNotFound, + /// The token decimals property was not found + #[error("tokenDecimals not found in properties")] + TokenDecimalsNotFound, + /// The cache is empty. + #[error("Cache is empty")] + CacheEmpty, +} + +// Convert a `ClientError` to an RPC `ErrorObjectOwned`. +impl From for ErrorObjectOwned { + fn from(_value: ClientError) -> Self { + ErrorObjectOwned::owned::<()>( + ErrorCode::InternalError.code(), + ErrorCode::InternalError.message(), + None, + ) + } +} + +/// The number of recent blocks maintained by the cache. +/// For each block in the cache, we also store the EVM transaction receipts. +pub const CACHE_SIZE: usize = 10; + +impl BlockCache { + fn latest_block(&self) -> Option<&Arc> { + self.buffer.back() + } + + /// Insert an entry into the cache, and prune the oldest entry if the cache is full. + fn insert(&mut self, block: SubstrateBlock) { + if self.buffer.len() >= N { + if let Some(block) = self.buffer.pop_front() { + log::trace!(target: LOG_TARGET, "Pruning block: {}", block.number()); + let hash = block.hash(); + self.blocks_by_hash.remove(&hash); + self.blocks_by_number.remove(&block.number()); + if let Some(entries) = self.tx_hashes_by_block_and_index.remove(&hash) { + for hash in entries.values() { + self.receipts_by_hash.remove(hash); + } + } + } + } + + let block = Arc::new(block); + self.buffer.push_back(block.clone()); + self.blocks_by_number.insert(block.number(), block.clone()); + self.blocks_by_hash.insert(block.hash(), block); + } +} + +/// A client connect to a node and maintains a cache of the last `CACHE_SIZE` blocks. +pub struct Client { + inner: Arc, + join_set: JoinSet>, + /// A watch channel to signal cache updates. + pub updates: tokio::sync::watch::Receiver<()>, +} + +/// The inner state of the client. +struct ClientInner { + api: OnlineClient, + rpc_client: ReconnectingRpcClient, + rpc: LegacyRpcMethods, + cache: Shared>, + chain_id: u64, + max_block_weight: Weight, + native_to_evm_ratio: U256, +} + +impl ClientInner { + /// Create a new client instance connecting to the substrate node at the given URL. + async fn from_url(url: &str) -> Result { + let rpc_client = ReconnectingRpcClient::builder() + .retry_policy(ExponentialBackoff::from_millis(100).max_delay(Duration::from_secs(10))) + .build(url.to_string()) + .await?; + + let api = OnlineClient::::from_rpc_client(rpc_client.clone()).await?; + let cache = Arc::new(RwLock::new(BlockCache::::default())); + + let rpc = LegacyRpcMethods::::new(RpcClient::new(rpc_client.clone())); + + let (native_to_evm_ratio, chain_id, max_block_weight) = + tokio::try_join!(native_to_evm_ratio(&rpc), chain_id(&api), max_block_weight(&api))?; + + Ok(Self { api, rpc_client, rpc, cache, chain_id, max_block_weight, native_to_evm_ratio }) + } + + /// Convert a native balance to an EVM balance. + pub fn native_to_evm_decimals(&self, value: U256) -> U256 { + value.saturating_mul(self.native_to_evm_ratio) + } + + /// Get the receipt infos from the extrinsics in a block. + async fn receipt_infos( + &self, + block: &SubstrateBlock, + ) -> Result, ClientError> { + // Get extrinsics from the block + let extrinsics = block.extrinsics().await?; + + // Filter extrinsics from pallet_revive + let extrinsics = extrinsics.iter().flat_map(|ext| { + let ext = ext.ok()?; + + let call = ext.as_extrinsic::().ok()??; + let tx = rlp::decode::(&call.payload).ok()?; + let from = tx.recover_eth_address().ok()?; + let contract_address = if tx.transaction_legacy_unsigned.to.is_none() { + Some(create1(&from, tx.transaction_legacy_unsigned.nonce.try_into().ok()?)) + } else { + None + }; + + Some((from, tx, contract_address, ext)) + }); + + // Map each extrinsic to a receipt + stream::iter(extrinsics) + .map(|(from, tx, contract_address, ext)| async move { + let events = ext.events().await?; + let tx_fees = + events.find_first::()?.ok_or(ClientError::TxFeeNotFound)?; + + let gas_price = tx.transaction_legacy_unsigned.gas_price; + let gas_used = (tx_fees.tip.saturating_add(tx_fees.actual_fee)) + .checked_div(gas_price.as_u128()) + .unwrap_or_default(); + + let success = events.find_first::().is_ok(); + let transaction_index = ext.index(); + let transaction_hash = primitives::Hashing::hash(&Vec::from(ext.bytes()).encode()); + let block_hash = block.hash(); + let block_number = block.number().into(); + + let receipt = ReceiptInfo { + block_hash, + block_number, + contract_address, + from, + to: tx.transaction_legacy_unsigned.to, + effective_gas_price: gas_price, + gas_used: gas_used.into(), + status: Some(if success { U256::one() } else { U256::zero() }), + transaction_hash, + transaction_index: transaction_index.into(), + ..Default::default() + }; + + Ok::<_, ClientError>((receipt.transaction_hash, (tx.into(), receipt))) + }) + .buffer_unordered(10) + .collect::>>() + .await + .into_iter() + .collect::, _>>() + } +} + +/// Drop all the tasks spawned by the client on drop. +impl Drop for Client { + fn drop(&mut self) { + self.join_set.abort_all() + } +} + +/// Fetch the chain ID from the substrate chain. +async fn chain_id(api: &OnlineClient) -> Result { + let query = subxt_client::constants().revive().chain_id(); + api.constants().at(&query).map_err(|err| err.into()) +} + +/// Fetch the max block weight from the substrate chain. +async fn max_block_weight(api: &OnlineClient) -> Result { + let query = subxt_client::constants().system().block_weights(); + let weights = api.constants().at(&query)?; + let max_block = weights.per_class.normal.max_extrinsic.unwrap_or(weights.max_block); + Ok(max_block.0) +} + +/// Fetch the native to EVM ratio from the substrate chain. +async fn native_to_evm_ratio(rpc: &LegacyRpcMethods) -> Result { + let props = rpc.system_properties().await?; + let eth_decimals = U256::from(18u32); + let native_decimals: U256 = props + .get("tokenDecimals") + .and_then(|v| v.as_number()?.as_u64()) + .ok_or(ClientError::TokenDecimalsNotFound)? + .into(); + + Ok(U256::from(10u32).pow(eth_decimals - native_decimals)) +} + +/// Extract the block timestamp. +async fn extract_block_timestamp(block: &SubstrateBlock) -> Option { + let extrinsics = block.extrinsics().await.ok()?; + let ext = extrinsics + .find_first::() + .ok()??; + + Some(ext.value.now / 1000) +} + +impl Client { + /// Create a new client instance. + /// The client will subscribe to new blocks and maintain a cache of [`CACHE_SIZE`] blocks. + pub async fn from_url(url: &str) -> Result { + log::info!(target: LOG_TARGET, "Connecting to node at: {url} ..."); + let inner: Arc = Arc::new(ClientInner::from_url(url).await?); + log::info!(target: LOG_TARGET, "Connected to node at: {url}"); + + let (tx, mut updates) = tokio::sync::watch::channel(()); + let mut join_set = JoinSet::new(); + join_set.spawn(Self::subscribe_blocks(inner.clone(), tx)); + join_set.spawn(Self::subscribe_reconnect(inner.clone())); + + updates.changed().await.expect("tx is not dropped"); + Ok(Self { inner, join_set, updates }) + } + + /// Subscribe and log reconnection events. + async fn subscribe_reconnect(inner: Arc) -> Result<(), ClientError> { + let rpc = inner.as_ref().rpc_client.clone(); + loop { + let reconnected = rpc.reconnect_initiated().await; + log::info!("RPC client connection lost"); + let now = std::time::Instant::now(); + reconnected.await; + log::info!("RPC client reconnection took `{}s`", now.elapsed().as_secs()); + } + } + + /// Subscribe to new blocks and update the cache. + async fn subscribe_blocks(inner: Arc, tx: Sender<()>) -> Result<(), ClientError> { + log::info!("Subscribing to new blocks"); + let mut block_stream = + inner.as_ref().api.blocks().subscribe_finalized().await.inspect_err(|err| { + log::error!("Failed to subscribe to blocks: {err:?}"); + })?; + + while let Some(block) = block_stream.next().await { + let block = match block { + Ok(block) => block, + Err(err) => { + if err.is_disconnected_will_reconnect() { + log::warn!( + "The RPC connection was lost and we may have missed a few blocks" + ); + continue; + } + + log::error!("Failed to fetch block: {err:?}"); + return Err(err.into()); + }, + }; + + log::debug!("Pushing block: {}", block.number()); + let mut cache = inner.cache.write().await; + + let receipts = inner + .receipt_infos(&block) + .await + .inspect_err(|err| { + log::error!("Failed to get receipts: {err:?}"); + }) + .unwrap_or_default(); + + if !receipts.is_empty() { + log::debug!("Adding {} receipts", receipts.len()); + let values = receipts + .iter() + .map(|(hash, (_, receipt))| (receipt.transaction_index, *hash)) + .collect::>(); + + cache.tx_hashes_by_block_and_index.insert(block.hash(), values); + + cache + .receipts_by_hash + .extend(receipts.iter().map(|(hash, (_, receipt))| (*hash, receipt.clone()))); + + cache.signed_tx_by_hash.extend( + receipts.iter().map(|(hash, (signed_tx, _))| (*hash, signed_tx.clone())), + ) + } + + cache.insert(block); + tx.send_replace(()); + } + + log::info!("Block subscription ended"); + Ok(()) + } + + /// Get the most recent block stored in the cache. + pub async fn latest_block(&self) -> Option> { + let cache = self.inner.cache.read().await; + let block = cache.latest_block()?; + Some(block.clone()) + } + + /// Expose the transaction API. + pub fn tx(&self) -> TxClient> { + self.inner.api.tx() + } + + /// Get an EVM transaction receipt by hash. + pub async fn receipt(&self, tx_hash: &H256) -> Option { + let cache = self.inner.cache.read().await; + cache.receipts_by_hash.get(tx_hash).cloned() + } + + /// Get an EVM transaction receipt by hash. + pub async fn receipt_by_hash_and_index( + &self, + block_hash: &H256, + transaction_index: &U256, + ) -> Option { + let cache = self.inner.cache.read().await; + let receipt_hash = + cache.tx_hashes_by_block_and_index.get(block_hash)?.get(transaction_index)?; + let receipt = cache.receipts_by_hash.get(receipt_hash)?; + Some(receipt.clone()) + } + + pub async fn signed_tx_by_hash(&self, tx_hash: &H256) -> Option { + let cache = self.inner.cache.read().await; + cache.signed_tx_by_hash.get(tx_hash).cloned() + } + + /// Get receipts count per block. + pub async fn receipts_count_per_block(&self, block_hash: &SubstrateBlockHash) -> Option { + let cache = self.inner.cache.read().await; + cache.tx_hashes_by_block_and_index.get(block_hash).map(|v| v.len()) + } + + /// Expose the storage API. + pub async fn storage_api( + &self, + at: &BlockNumberOrTagOrHash, + ) -> Result>, ClientError> { + match at { + BlockNumberOrTagOrHash::U256(block_number) => { + let n: SubstrateBlockNumber = + (*block_number).try_into().map_err(|_| ClientError::ConversionFailed)?; + + let hash = self.get_block_hash(n).await?.ok_or(ClientError::BlockNotFound)?; + Ok(self.inner.api.storage().at(hash)) + }, + BlockNumberOrTagOrHash::H256(hash) => Ok(self.inner.api.storage().at(*hash)), + BlockNumberOrTagOrHash::BlockTag(_) => { + if let Some(block) = self.latest_block().await { + return Ok(self.inner.api.storage().at(block.hash())); + } + let storage = self.inner.api.storage().at_latest().await?; + Ok(storage) + }, + } + } + + /// Expose the runtime API. + pub async fn runtime_api( + &self, + at: &BlockNumberOrTagOrHash, + ) -> Result< + subxt::runtime_api::RuntimeApi>, + ClientError, + > { + match at { + BlockNumberOrTagOrHash::U256(block_number) => { + let n: SubstrateBlockNumber = + (*block_number).try_into().map_err(|_| ClientError::ConversionFailed)?; + + let hash = self.get_block_hash(n).await?.ok_or(ClientError::BlockNotFound)?; + Ok(self.inner.api.runtime_api().at(hash)) + }, + BlockNumberOrTagOrHash::H256(hash) => Ok(self.inner.api.runtime_api().at(*hash)), + BlockNumberOrTagOrHash::BlockTag(_) => { + if let Some(block) = self.latest_block().await { + return Ok(self.inner.api.runtime_api().at(block.hash())); + } + + let api = self.inner.api.runtime_api().at_latest().await?; + Ok(api) + }, + } + } + + /// Get the balance of the given address. + pub async fn balance( + &self, + address: H160, + at: &BlockNumberOrTagOrHash, + ) -> Result { + let account_id = self.account_id(&address); + let query = subxt_client::storage().system().account(account_id); + let Some(account) = self.storage_api(at).await?.fetch(&query).await? else { + return Ok(U256::zero()); + }; + + let native = account.data.free.into(); + Ok(self.inner.native_to_evm_decimals(native)) + } + + /// Get the contract storage for the given contract address and key. + pub async fn get_contract_storage( + &self, + contract_address: H160, + key: U256, + block: BlockNumberOrTagOrHash, + ) -> Result, ClientError> { + let runtime_api = self.runtime_api(&block).await?; + + let mut bytes = [0u8; 32]; + key.to_big_endian(&mut bytes); + + let payload = subxt_client::apis().revive_api().get_storage(contract_address, bytes); + let result = runtime_api.call(payload).await?.unwrap_or_default().unwrap_or_default(); + Ok(result) + } + + /// Get the contract code for the given contract address. + pub async fn get_contract_code( + &self, + contract_address: &H160, + block: BlockNumberOrTagOrHash, + ) -> Result, ClientError> { + let storage_api = self.storage_api(&block).await?; + let account_id = self.account_id(contract_address); + let code_hash: H256 = account_id.0.into(); + let query = subxt_client::storage().revive().pristine_code(code_hash); + let result = storage_api.fetch(&query).await?.map(|v| v.0).unwrap_or_default(); + Ok(result) + } + + /// Dry run a transaction and returns the [`DryRunInfo`] for the transaction. + pub async fn dry_run( + &self, + tx: &GenericTransaction, + block: BlockNumberOrTagOrHash, + ) -> Result, ClientError> { + let runtime_api = self.runtime_api(&block).await?; + let from = tx.from.ok_or(ClientError::DryRunFailed)?; + let value = tx + .value + .unwrap_or_default() + .try_into() + .map_err(|_| ClientError::ConversionFailed)?; + + let payload = subxt_client::apis().revive_api().eth_transact( + from, + tx.to, + value, + tx.input.clone().unwrap_or_default().0, + None, + None, + ); + let res = runtime_api.call(payload).await?.0; + Ok(res) + } + + /// Dry run a transaction and returns the gas estimate for the transaction. + pub async fn estimate_gas( + &self, + tx: &GenericTransaction, + block: BlockNumberOrTagOrHash, + ) -> Result { + let dry_run = self.dry_run(tx, block).await?; + Ok(U256::from(dry_run.fee / GAS_PRICE) + 1) + } + + /// Get the nonce of the given address. + pub async fn nonce( + &self, + address: H160, + block: BlockNumberOrTagOrHash, + ) -> Result { + let account_id = self.account_id(&address); + let storage = self.storage_api(&block).await?; + let query = subxt_client::storage().system().account(account_id); + let Some(account) = storage.fetch(&query).await? else { + return Ok(0); + }; + + Ok(account.nonce) + } + + /// Get the block number of the latest block. + pub async fn block_number(&self) -> Result { + let cache = self.inner.cache.read().await; + let latest_block = cache.buffer.back().ok_or(ClientError::CacheEmpty)?; + Ok(latest_block.number()) + } + + /// Get a block hash for the given block number. + pub async fn get_block_hash( + &self, + block_number: SubstrateBlockNumber, + ) -> Result, ClientError> { + let cache = self.inner.cache.read().await; + if let Some(block) = cache.blocks_by_number.get(&block_number) { + return Ok(Some(block.hash())); + } + + let hash = self.inner.rpc.chain_get_block_hash(Some(block_number.into())).await?; + Ok(hash) + } + + /// Get a block for the specified hash or number. + pub async fn block_by_number_or_tag( + &self, + block: &BlockNumberOrTag, + ) -> Result>, ClientError> { + match block { + BlockNumberOrTag::U256(n) => { + let n = (*n).try_into().map_err(|_| ClientError::ConversionFailed)?; + self.block_by_number(n).await + }, + BlockNumberOrTag::BlockTag(_) => { + let cache = self.inner.cache.read().await; + Ok(cache.buffer.back().cloned()) + }, + } + } + + /// Get a block by hash + pub async fn block_by_hash( + &self, + hash: &SubstrateBlockHash, + ) -> Result>, ClientError> { + let cache = self.inner.cache.read().await; + if let Some(block) = cache.blocks_by_hash.get(hash) { + return Ok(Some(block.clone())); + } + + match self.inner.api.blocks().at(*hash).await { + Ok(block) => Ok(Some(Arc::new(block))), + Err(subxt::Error::Block(subxt::error::BlockError::NotFound(_))) => Ok(None), + Err(err) => Err(err.into()), + } + } + + /// Get a block by number + pub async fn block_by_number( + &self, + block_number: SubstrateBlockNumber, + ) -> Result>, ClientError> { + let cache = self.inner.cache.read().await; + if let Some(block) = cache.blocks_by_number.get(&block_number) { + return Ok(Some(block.clone())); + } + + let Some(hash) = self.get_block_hash(block_number).await? else { + return Ok(None); + }; + + self.block_by_hash(&hash).await + } + + /// Get the EVM block for the given hash. + pub async fn evm_block(&self, block: Arc) -> Result { + let runtime_api = self.inner.api.runtime_api().at(block.hash()); + let max_fee = Self::weight_to_fee(&runtime_api, self.max_block_weight()).await?; + let gas_limit = U256::from(max_fee / GAS_PRICE); + + let header = block.header(); + let timestamp = extract_block_timestamp(&block).await.unwrap_or_default(); + Ok(Block { + hash: block.hash(), + parent_hash: header.parent_hash, + state_root: header.state_root, + transactions_root: header.extrinsics_root, + number: header.number.into(), + timestamp: timestamp.into(), + gas_limit, + logs_bloom: Bytes256([0u8; 256]), + receipts_root: header.extrinsics_root, + ..Default::default() + }) + } + + /// Convert a weight to a fee. + async fn weight_to_fee( + runtime_api: &subxt::runtime_api::RuntimeApi>, + weight: Weight, + ) -> Result { + let payload = subxt_client::apis() + .transaction_payment_api() + .query_weight_to_fee(weight.into()); + + let fee = runtime_api.call(payload).await?; + Ok(fee) + } + + /// Get the substrate account ID from the EVM address. + pub fn account_id(&self, address: &H160) -> AccountId32 { + let mut id: [u8; 32] = [0xEE; 32]; + id[..20].copy_from_slice(address.as_bytes()); + AccountId32(id) + } + + /// Get the chain ID. + pub fn chain_id(&self) -> u64 { + self.inner.chain_id + } + + /// Get the Max Block Weight. + pub fn max_block_weight(&self) -> Weight { + self.inner.max_block_weight + } +} diff --git a/substrate/frame/revive/rpc/src/example.rs b/substrate/frame/revive/rpc/src/example.rs new file mode 100644 index 000000000000..d1c39aa95d23 --- /dev/null +++ b/substrate/frame/revive/rpc/src/example.rs @@ -0,0 +1,114 @@ +//! Example utilities +#![cfg(feature = "example")] + +use anyhow::Context; +use jsonrpsee::http_client::HttpClient; +use pallet_revive::evm::{ + rlp::*, BlockTag, Bytes, EthRpcClient, GenericTransaction, TransactionLegacySigned, + TransactionLegacyUnsigned, H160, H256, U256, +}; +use secp256k1::{Message, PublicKey, Secp256k1, SecretKey}; +use sp_core::keccak_256; +use std::str::FromStr; + +/// A simple account that can sign transactions +pub struct Account { + /// The secret key of the account + sk: SecretKey, +} + +impl Default for Account { + fn default() -> Self { + Account { + sk: SecretKey::from_str( + "a872f6cbd25a0e04a08b1e21098017a9e6194d101d75e13111f71410c59cd57f", + ) + .unwrap(), + } + } +} + +impl Account { + /// Create an account from a keypair. + pub fn from_keypair(pair: &subxt_signer::ecdsa::Keypair) -> Self { + let sb = pair.0.secret_key().secret_bytes(); + Account { sk: SecretKey::from_slice(&sb).unwrap() } + } + + /// Get the [`H160`] address of the account. + pub fn address(&self) -> H160 { + let pub_key = + PublicKey::from_secret_key(&Secp256k1::new(), &self.sk).serialize_uncompressed(); + let hash = keccak_256(&pub_key[1..]); + H160::from_slice(&hash[12..]) + } + + /// Sign a transaction. + pub fn sign_transaction(&self, tx: TransactionLegacyUnsigned) -> TransactionLegacySigned { + let rlp_encoded = tx.rlp_bytes(); + let tx_hash = keccak_256(&rlp_encoded); + let secp = Secp256k1::new(); + let msg = Message::from_digest(tx_hash); + let sig = secp.sign_ecdsa_recoverable(&msg, &self.sk); + let (recovery_id, sig) = sig.serialize_compact(); + let sig = sig.into_iter().chain([recovery_id.to_i32() as u8]).collect::>(); + TransactionLegacySigned::from(tx, &sig.try_into().unwrap()) + } + + /// Send a transaction. + pub async fn send_transaction( + &self, + client: &HttpClient, + value: U256, + input: Bytes, + to: Option, + ) -> anyhow::Result { + let from = self.address(); + + let chain_id = Some(client.chain_id().await?); + + let gas_price = client.gas_price().await?; + let nonce = client + .get_transaction_count(from, BlockTag::Latest.into()) + .await + .with_context(|| "Failed to fetch account nonce")?; + + let gas = client + .estimate_gas( + GenericTransaction { + from: Some(from), + input: Some(input.clone()), + value: Some(value), + gas_price: Some(gas_price), + to, + ..Default::default() + }, + None, + ) + .await + .with_context(|| "Failed to fetch gas estimate")?; + + println!("Estimated Gas: {gas:?}"); + + let unsigned_tx = TransactionLegacyUnsigned { + gas, + nonce, + to, + value, + input, + gas_price, + chain_id, + ..Default::default() + }; + + let tx = self.sign_transaction(unsigned_tx.clone()); + let bytes = tx.rlp_bytes().to_vec(); + + let hash = client + .send_raw_transaction(bytes.clone().into()) + .await + .with_context(|| "transaction failed")?; + + Ok(hash) + } +} diff --git a/substrate/frame/revive/rpc/src/lib.rs b/substrate/frame/revive/rpc/src/lib.rs new file mode 100644 index 000000000000..5bbed3c3af09 --- /dev/null +++ b/substrate/frame/revive/rpc/src/lib.rs @@ -0,0 +1,305 @@ +//! The [`EthRpcServer`] RPC server implementation +#![cfg_attr(docsrs, feature(doc_cfg))] + +use client::{ClientError, GAS_PRICE}; +use jsonrpsee::{ + core::{async_trait, RpcResult}, + proc_macros::rpc, + types::{ErrorCode, ErrorObjectOwned}, +}; +pub use pallet_revive::{evm::*, EthContractResult}; +pub use sp_core::{H160, H256, U256}; +use thiserror::Error; +pub mod client; +pub mod example; +pub mod subxt_client; + +mod rpc_methods_gen; +pub use rpc_methods_gen::*; + +pub const LOG_TARGET: &str = "eth-rpc"; + +/// Additional RPC methods, exposed on the RPC server on top of all the eth_xxx methods. +#[rpc(server, client)] +pub trait MiscRpc { + /// Returns the health status of the server. + #[method(name = "healthcheck")] + async fn healthcheck(&self) -> RpcResult<()>; +} + +/// An EVM RPC server implementation. +pub struct EthRpcServerImpl { + client: client::Client, +} + +impl EthRpcServerImpl { + /// Creates a new [`EthRpcServerImpl`]. + pub fn new(client: client::Client) -> Self { + Self { client } + } +} + +/// The error type for the EVM RPC server. +#[derive(Error, Debug)] +pub enum EthRpcError { + /// A [`ClientError`] wrapper error. + #[error("Client error: {0}")] + ClientError(#[from] ClientError), + /// A [`rlp::DecoderError`] wrapper error. + #[error("Decoding error: {0}")] + RlpError(#[from] rlp::DecoderError), + /// A Decimals conversion error. + #[error("Conversion error")] + ConversionError, + /// An invalid signature error. + #[error("Invalid signature")] + InvalidSignature, + /// The account was not found at the given address + #[error("Account not found for address {0:?}")] + AccountNotFound(H160), +} + +impl From for ErrorObjectOwned { + fn from(value: EthRpcError) -> Self { + let code = match value { + EthRpcError::ClientError(_) => ErrorCode::InternalError, + _ => ErrorCode::InvalidRequest, + }; + Self::owned::(code.code(), value.to_string(), None) + } +} + +#[async_trait] +impl EthRpcServer for EthRpcServerImpl { + async fn net_version(&self) -> RpcResult { + Ok(self.client.chain_id().to_string()) + } + + async fn block_number(&self) -> RpcResult { + let number = self.client.block_number().await?; + Ok(number.into()) + } + + async fn get_transaction_receipt( + &self, + transaction_hash: H256, + ) -> RpcResult> { + let receipt = self.client.receipt(&transaction_hash).await; + Ok(receipt) + } + + async fn estimate_gas( + &self, + transaction: GenericTransaction, + _block: Option, + ) -> RpcResult { + let result = self.client.estimate_gas(&transaction, BlockTag::Latest.into()).await?; + Ok(result) + } + + async fn send_raw_transaction(&self, transaction: Bytes) -> RpcResult { + let tx = rlp::decode::(&transaction.0).map_err(|err| { + log::debug!(target: LOG_TARGET, "Failed to decode transaction: {err:?}"); + EthRpcError::from(err) + })?; + + let eth_addr = tx.recover_eth_address().map_err(|err| { + log::debug!(target: LOG_TARGET, "Failed to recover eth address: {err:?}"); + EthRpcError::InvalidSignature + })?; + + // Dry run the transaction to get the weight limit and storage deposit limit + let TransactionLegacyUnsigned { to, input, value, .. } = tx.transaction_legacy_unsigned; + let dry_run = self + .client + .dry_run( + &GenericTransaction { + from: Some(eth_addr), + input: Some(input.clone()), + to, + value: Some(value), + ..Default::default() + }, + BlockTag::Latest.into(), + ) + .await?; + + let EthContractResult { kind, gas_limit, storage_deposit, .. } = dry_run; + let call = subxt_client::tx().revive().eth_transact( + transaction.0, + gas_limit.into(), + storage_deposit, + kind.into(), + ); + let ext = self.client.tx().create_unsigned(&call).map_err(|err| ClientError::from(err))?; + let hash = ext.submit().await.map_err(|err| EthRpcError::ClientError(err.into()))?; + + Ok(hash) + } + + async fn get_block_by_hash( + &self, + block_hash: H256, + _hydrated_transactions: bool, + ) -> RpcResult> { + let Some(block) = self.client.block_by_hash(&block_hash).await? else { + return Ok(None); + }; + let block = self.client.evm_block(block).await?; + Ok(Some(block)) + } + + async fn get_balance( + &self, + address: Address, + block: BlockNumberOrTagOrHash, + ) -> RpcResult { + let balance = self.client.balance(address, &block).await?; + log::debug!(target: LOG_TARGET, "balance({address}): {balance:?}"); + Ok(balance) + } + + async fn chain_id(&self) -> RpcResult { + Ok(self.client.chain_id().into()) + } + + async fn gas_price(&self) -> RpcResult { + Ok(U256::from(GAS_PRICE)) + } + + async fn get_code(&self, address: Address, block: BlockNumberOrTagOrHash) -> RpcResult { + let code = self.client.get_contract_code(&address, block).await?; + Ok(code.into()) + } + + async fn accounts(&self) -> RpcResult> { + Ok(vec![]) + } + + async fn call( + &self, + transaction: GenericTransaction, + block: Option, + ) -> RpcResult { + let dry_run = self + .client + .dry_run(&transaction, block.unwrap_or_else(|| BlockTag::Latest.into())) + .await?; + let output = dry_run.result.map_err(|err| { + log::debug!(target: LOG_TARGET, "Dry run failed: {err:?}"); + ClientError::DryRunFailed + })?; + + Ok(output.into()) + } + + async fn get_block_by_number( + &self, + block: BlockNumberOrTag, + _hydrated_transactions: bool, + ) -> RpcResult> { + let Some(block) = self.client.block_by_number_or_tag(&block).await? else { + return Ok(None); + }; + let block = self.client.evm_block(block).await?; + Ok(Some(block)) + } + + async fn get_block_transaction_count_by_hash( + &self, + block_hash: Option, + ) -> RpcResult> { + let block_hash = if let Some(block_hash) = block_hash { + block_hash + } else { + self.client.latest_block().await.ok_or(ClientError::BlockNotFound)?.hash() + }; + Ok(self.client.receipts_count_per_block(&block_hash).await.map(U256::from)) + } + + async fn get_block_transaction_count_by_number( + &self, + block: Option, + ) -> RpcResult> { + let Some(block) = self + .get_block_by_number(block.unwrap_or_else(|| BlockTag::Latest.into()), false) + .await? + else { + return Ok(None); + }; + + Ok(self.client.receipts_count_per_block(&block.hash).await.map(U256::from)) + } + + async fn get_storage_at( + &self, + address: Address, + storage_slot: U256, + block: BlockNumberOrTagOrHash, + ) -> RpcResult { + let bytes = self.client.get_contract_storage(address, storage_slot, block).await?; + Ok(bytes.into()) + } + + async fn get_transaction_by_block_hash_and_index( + &self, + block_hash: H256, + transaction_index: U256, + ) -> RpcResult> { + let Some(receipt) = + self.client.receipt_by_hash_and_index(&block_hash, &transaction_index).await + else { + return Ok(None); + }; + + let Some(signed_tx) = self.client.signed_tx_by_hash(&receipt.transaction_hash).await else { + return Ok(None); + }; + + Ok(Some(TransactionInfo::new(receipt, signed_tx))) + } + + async fn get_transaction_by_block_number_and_index( + &self, + block: BlockNumberOrTag, + transaction_index: U256, + ) -> RpcResult> { + let Some(block) = self.client.block_by_number_or_tag(&block).await? else { + return Ok(None); + }; + self.get_transaction_by_block_hash_and_index(block.hash(), transaction_index) + .await + } + + async fn get_transaction_by_hash( + &self, + transaction_hash: H256, + ) -> RpcResult> { + let receipt = self.client.receipt(&transaction_hash).await; + let signed_tx = self.client.signed_tx_by_hash(&transaction_hash).await; + if let (Some(receipt), Some(signed_tx)) = (receipt, signed_tx) { + return Ok(Some(TransactionInfo::new(receipt, signed_tx))); + } + + Ok(None) + } + + async fn get_transaction_count( + &self, + address: Address, + block: BlockNumberOrTagOrHash, + ) -> RpcResult { + let nonce = self.client.nonce(address, block).await?; + Ok(nonce.into()) + } +} + +/// A [`MiscRpcServer`] RPC server implementation. +pub struct MiscRpcServerImpl; + +#[async_trait] +impl MiscRpcServer for MiscRpcServerImpl { + async fn healthcheck(&self) -> RpcResult<()> { + Ok(()) + } +} diff --git a/substrate/frame/revive/rpc/src/main.rs b/substrate/frame/revive/rpc/src/main.rs new file mode 100644 index 000000000000..06e1d2a0de68 --- /dev/null +++ b/substrate/frame/revive/rpc/src/main.rs @@ -0,0 +1,128 @@ +//! The Ethereum JSON-RPC server. +use clap::Parser; +use hyper::Method; +use jsonrpsee::{ + http_client::HttpClientBuilder, + server::{RpcModule, Server}, +}; +use pallet_revive_eth_rpc::{ + client::Client, EthRpcClient, EthRpcServer, EthRpcServerImpl, MiscRpcServer, MiscRpcServerImpl, + LOG_TARGET, +}; +use std::net::SocketAddr; +use tower_http::cors::{Any, CorsLayer}; +use tracing_subscriber::{util::SubscriberInitExt, EnvFilter, FmtSubscriber}; + +// Parsed command instructions from the command line +#[derive(Parser)] +#[clap(author, about, version)] +struct CliCommand { + /// The server address to bind to + #[clap(long, default_value = "127.0.0.1:9090")] + url: String, + + /// The node url to connect to + #[clap(long, default_value = "ws://127.0.0.1:9944")] + node_url: String, +} + +/// Initialize tracing +fn init_tracing() { + let env_filter = + EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("eth_rpc=trace")); + + FmtSubscriber::builder() + .with_env_filter(env_filter) + .finish() + .try_init() + .expect("failed to initialize tracing"); +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let CliCommand { url, node_url } = CliCommand::parse(); + init_tracing(); + + let client = Client::from_url(&node_url).await.unwrap(); + let mut updates = client.updates.clone(); + + let server_addr = run_server(client, &url).await?; + log::info!(target: LOG_TARGET, "Server started on: {}", server_addr); + + let url = format!("http://{}", server_addr); + let client = HttpClientBuilder::default().build(url)?; + + let response = client.block_number().await?; + log::info!(target: LOG_TARGET, "client initialized with block number {:?}", response); + + // keep running server until ctrl-c or client subscription fails + let _ = updates.wait_for(|_| false).await; + Ok(()) +} + +#[cfg(feature = "dev")] +mod dev { + use crate::LOG_TARGET; + use futures::{future::BoxFuture, FutureExt}; + use jsonrpsee::{server::middleware::rpc::RpcServiceT, types::Request, MethodResponse}; + + /// Dev Logger middleware, that logs the method and params of the request, along with the + /// success of the response. + #[derive(Clone)] + pub struct DevLogger(pub S); + + impl<'a, S> RpcServiceT<'a> for DevLogger + where + S: RpcServiceT<'a> + Send + Sync + Clone + 'static, + { + type Future = BoxFuture<'a, MethodResponse>; + + fn call(&self, req: Request<'a>) -> Self::Future { + let service = self.0.clone(); + let method = req.method.clone(); + let params = req.params.clone().unwrap_or_default(); + + async move { + log::info!(target: LOG_TARGET, "method: {method} params: {params}"); + let resp = service.call(req).await; + if resp.is_success() { + log::info!(target: LOG_TARGET, "✅ method: {method}"); + } else { + log::info!(target: LOG_TARGET, "❌ method: {method} {}", resp.as_result()); + } + resp + } + .boxed() + } + } +} + +/// Starts the rpc server and returns the server address. +async fn run_server(client: Client, url: &str) -> anyhow::Result { + let cors = CorsLayer::new() + .allow_methods([Method::POST]) + .allow_origin(Any) + .allow_headers([hyper::header::CONTENT_TYPE]); + let cors_middleware = tower::ServiceBuilder::new().layer(cors); + + let builder = Server::builder().set_http_middleware(cors_middleware); + + #[cfg(feature = "dev")] + let builder = builder + .set_rpc_middleware(jsonrpsee::server::RpcServiceBuilder::new().layer_fn(dev::DevLogger)); + + let server = builder.build(url.parse::()?).await?; + let addr = server.local_addr()?; + + let eth_api = EthRpcServerImpl::new(client).into_rpc(); + let misc_api = MiscRpcServerImpl.into_rpc(); + + let mut module = RpcModule::new(()); + module.merge(eth_api)?; + module.merge(misc_api)?; + + let handle = server.start(module); + tokio::spawn(handle.stopped()); + + Ok(addr) +} diff --git a/substrate/frame/revive/rpc/src/rpc_methods_gen.rs b/substrate/frame/revive/rpc/src/rpc_methods_gen.rs new file mode 100644 index 000000000000..eb6bebe232b4 --- /dev/null +++ b/substrate/frame/revive/rpc/src/rpc_methods_gen.rs @@ -0,0 +1,152 @@ +// 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. +//! Generated JSON-RPC methods. +#![allow(missing_docs)] + +use super::*; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; + +#[rpc(server, client)] +pub trait EthRpc { + /// Returns a list of addresses owned by client. + #[method(name = "eth_accounts")] + async fn accounts(&self) -> RpcResult>; + + /// Returns the number of most recent block. + #[method(name = "eth_blockNumber")] + async fn block_number(&self) -> RpcResult; + + /// Executes a new message call immediately without creating a transaction on the block chain. + #[method(name = "eth_call")] + async fn call( + &self, + transaction: GenericTransaction, + block: Option, + ) -> RpcResult; + + /// Returns the chain ID of the current network. + #[method(name = "eth_chainId")] + async fn chain_id(&self) -> RpcResult; + + /// Generates and returns an estimate of how much gas is necessary to allow the transaction to + /// complete. + #[method(name = "eth_estimateGas")] + async fn estimate_gas( + &self, + transaction: GenericTransaction, + block: Option, + ) -> RpcResult; + + /// Returns the current price per gas in wei. + #[method(name = "eth_gasPrice")] + async fn gas_price(&self) -> RpcResult; + + /// Returns the balance of the account of given address. + #[method(name = "eth_getBalance")] + async fn get_balance(&self, address: Address, block: BlockNumberOrTagOrHash) + -> RpcResult; + + /// Returns information about a block by hash. + #[method(name = "eth_getBlockByHash")] + async fn get_block_by_hash( + &self, + block_hash: H256, + hydrated_transactions: bool, + ) -> RpcResult>; + + /// Returns information about a block by number. + #[method(name = "eth_getBlockByNumber")] + async fn get_block_by_number( + &self, + block: BlockNumberOrTag, + hydrated_transactions: bool, + ) -> RpcResult>; + + /// Returns the number of transactions in a block from a block matching the given block hash. + #[method(name = "eth_getBlockTransactionCountByHash")] + async fn get_block_transaction_count_by_hash( + &self, + block_hash: Option, + ) -> RpcResult>; + + /// Returns the number of transactions in a block matching the given block number. + #[method(name = "eth_getBlockTransactionCountByNumber")] + async fn get_block_transaction_count_by_number( + &self, + block: Option, + ) -> RpcResult>; + + /// Returns code at a given address. + #[method(name = "eth_getCode")] + async fn get_code(&self, address: Address, block: BlockNumberOrTagOrHash) -> RpcResult; + + /// Returns the value from a storage position at a given address. + #[method(name = "eth_getStorageAt")] + async fn get_storage_at( + &self, + address: Address, + storage_slot: U256, + block: BlockNumberOrTagOrHash, + ) -> RpcResult; + + /// Returns information about a transaction by block hash and transaction index position. + #[method(name = "eth_getTransactionByBlockHashAndIndex")] + async fn get_transaction_by_block_hash_and_index( + &self, + block_hash: H256, + transaction_index: U256, + ) -> RpcResult>; + + /// Returns information about a transaction by block number and transaction index position. + #[method(name = "eth_getTransactionByBlockNumberAndIndex")] + async fn get_transaction_by_block_number_and_index( + &self, + block: BlockNumberOrTag, + transaction_index: U256, + ) -> RpcResult>; + + /// Returns the information about a transaction requested by transaction hash. + #[method(name = "eth_getTransactionByHash")] + async fn get_transaction_by_hash( + &self, + transaction_hash: H256, + ) -> RpcResult>; + + /// Returns the number of transactions sent from an address. + #[method(name = "eth_getTransactionCount")] + async fn get_transaction_count( + &self, + address: Address, + block: BlockNumberOrTagOrHash, + ) -> RpcResult; + + /// Returns the receipt of a transaction by transaction hash. + #[method(name = "eth_getTransactionReceipt")] + async fn get_transaction_receipt( + &self, + transaction_hash: H256, + ) -> RpcResult>; + + /// Submits a raw transaction. For EIP-4844 transactions, the raw form must be the network form. + /// This means it includes the blobs, KZG commitments, and KZG proofs. + #[method(name = "eth_sendRawTransaction")] + async fn send_raw_transaction(&self, transaction: Bytes) -> RpcResult; + + /// The string value of current network id + #[method(name = "net_version")] + async fn net_version(&self) -> RpcResult; +} diff --git a/substrate/frame/revive/rpc/src/subxt_client.rs b/substrate/frame/revive/rpc/src/subxt_client.rs new file mode 100644 index 000000000000..eaff1b021f03 --- /dev/null +++ b/substrate/frame/revive/rpc/src/subxt_client.rs @@ -0,0 +1,45 @@ +//! The generated subxt client. +use subxt::config::{signed_extensions, Config, PolkadotConfig}; + +#[subxt::subxt( + runtime_metadata_path = "metadata.scale", + substitute_type( + path = "pallet_revive::primitives::EthContractResult", + with = "::subxt::utils::Static<::pallet_revive::EthContractResult>" + ), + substitute_type( + path = "pallet_revive::primitives::EthTransactKind", + with = "::subxt::utils::Static<::pallet_revive::EthTransactKind>" + ), + substitute_type( + path = "sp_weights::weight_v2::Weight", + with = "::subxt::utils::Static<::sp_weights::Weight>" + ) +)] +mod src_chain {} +pub use src_chain::*; + +/// The configuration for the source chain. +pub enum SrcChainConfig {} +impl Config for SrcChainConfig { + type Hash = ::Hash; + type AccountId = ::AccountId; + type Address = ::Address; + type Signature = ::Signature; + type Hasher = ::Hasher; + type Header = ::Header; + type AssetId = ::AssetId; + type ExtrinsicParams = signed_extensions::AnyOf< + Self, + ( + signed_extensions::CheckSpecVersion, + signed_extensions::CheckTxVersion, + signed_extensions::CheckNonce, + signed_extensions::CheckGenesis, + signed_extensions::CheckMortality, + signed_extensions::ChargeAssetTxPayment, + signed_extensions::ChargeTransactionPayment, + signed_extensions::CheckMetadataHash, + ), + >; +} From 19dbf4c94ba2cb934312f23aa085d3aff80c2268 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Mon, 7 Oct 2024 21:04:22 +0200 Subject: [PATCH 02/37] wip --- substrate/bin/node/cli/src/chain_spec.rs | 8 ++++++++ substrate/frame/revive/rpc/Makefile | 4 ++-- substrate/frame/revive/rpc/kitchensink.scale | Bin 651254 -> 651612 bytes substrate/frame/revive/rpc/src/main.rs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/substrate/bin/node/cli/src/chain_spec.rs b/substrate/bin/node/cli/src/chain_spec.rs index bc7821bfcf30..e0cad10c6f9c 100644 --- a/substrate/bin/node/cli/src/chain_spec.rs +++ b/substrate/bin/node/cli/src/chain_spec.rs @@ -20,6 +20,7 @@ use polkadot_sdk::*; +use crate::chain_spec::sc_service::Properties; use kitchensink_runtime::{ constants::currency::*, wasm_binary_unwrap, Block, MaxNominations, SessionKeys, StakerStatus, }; @@ -447,12 +448,19 @@ fn development_config_genesis_json() -> serde_json::Value { ) } +fn props() -> Properties { + let mut properties = Properties::new(); + properties.insert("tokenDecimals".to_string(), "12".into()); + properties +} + /// Development config (single validator Alice). pub fn development_config() -> ChainSpec { ChainSpec::builder(wasm_binary_unwrap(), Default::default()) .with_name("Development") .with_id("dev") .with_chain_type(ChainType::Development) + .with_properties(props()) .with_genesis_config_patch(development_config_genesis_json()) .build() } diff --git a/substrate/frame/revive/rpc/Makefile b/substrate/frame/revive/rpc/Makefile index 64db1396a46c..6cf88b3b9ede 100644 --- a/substrate/frame/revive/rpc/Makefile +++ b/substrate/frame/revive/rpc/Makefile @@ -15,8 +15,8 @@ metadata: ifndef CHAIN $(error CHAIN is not defined. Please specify it when running make, e.g., make metadata CHAIN=) endif - @subxt explore --url ws://localhost:9944 pallet Revive constants chainId > /dev/null - subxt metadata --url ws://localhost:9944 -o $(CHAIN).scale + @subxt explore --url ws://localhost:9944 pallet Revive constants chainId > /dev/null + subxt metadata --url ws://localhost:9944 -o $(CHAIN).scale touch src/subxt_client.rs SALT ?= 0 diff --git a/substrate/frame/revive/rpc/kitchensink.scale b/substrate/frame/revive/rpc/kitchensink.scale index f9b520e7d67ad65ffacced036616f7eda0fdebf4..ceb4c6ba3ea2df0d0183637825654c3b7a0a6e18 100644 GIT binary patch delta 3376 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 B?5F?$ delta 3105 zcmZuz4Nz3q6~6cJ*t<8%zDETMDn=xTYa&@1XcvE4iEJXK1QgV0Yv~qV!V1gc?qZ;o zI;5duJ2r_9Il;)ZRB1wlshY7*XNn5`A_{KBA5@~oG99#7nTeU2%1qDOr*+?KXLk19 zci;KG^WE>>d+xjbWy;q#QcP~e@07OGnd(in-XzqUBI-?It0}TM!ddCs%$p-s-fa5d z5!AkCnhB%rkrMPavA+pq5GtEk98CV0Eu}-?{Fu$8A3?&0riW_nPNrJmkNZtCr`@s; zBF-MRj95l3W0nV&aSN3qr6?&@BE#^golSwo?aW3;^#1SK+4JCQXH#LIou$Abtv9)Y z&4mAGy@C!lYr;bdo#^m733+JQeqM-CKk8sRWje0o^A58YD20uO**q~)GB-eOR^+$0 z-?L7D>xbF=crMW;d6j;br(!|jym?tZpW@Fc`92{WY)4o!je_4FVKZRE5jK57v_$1x zPl-ZEv^Khk#=^}bEM16~w5%}aD9$zkaf}`Cm9tyfy55?r}CJEk_b(yjcZ3$Y%f*d&PkRCTTZexo6A7s)@as0vA`WdvmX0sm|KIcf{~MG zMDZ!MkXAv3OzLYLuwBoX|LB1G?pFg?;B(LTaO7hE3WGOCPUs zQ^*8MgY#?Bxb3tVXn-YR)7H!8BYQC6+X0qiYc*(X3)kAFYt(PVP^|Jzc4i5KY&VW9j!QeVzF^j&yo}>B#KxaQ5GIW>7$_I5*C>sTw-n-t@W2;LH+k7_8n_1 z5S;?9N112#Xlc-~~Ml{F8kz@nF8V<1P04uayVX=^N1&hQ> zSJ-6u%N4wws^A}2*blKuA7sg?X@;4nqh%S$7c9EzPc6&P2{T~xAp7g4OasOiim`=Z z78-)Hv_<(}hAgCgQW_tp(1t{_L(Y|n1G_?wOmbv%wy(0t?e-Q`dR=Z8bYEpw*ngG9 zet3g zhRAhcAGd`zBq%abpz%6x1{XvOu~qZkNb+gesZf4<~JJ=A;H1hw##` zh3+Ai@=TrfKG{s_W!RfVC#(Dmc07s>ZSK3v)V{msNq?p>@Z}Evg(~mloYFycN;BUc zxoOCfPsC;+Qy3F(S!OR;T&fh8;f=dS@p=lBiW0>;Y-v~&94)9+idQOL&4&?-Y!8kV zRzDsYwaB*M$g4_);&b`NEa`eguE*BVOZGY zS0_lbe^%}(E-S(XE=^ynj(y4(3z8x|=kq)LiYBCoxzxpb_-8^yl~kkN@8J0YtyQ!3 z@_Q3$9oRbgCcG5)cJf8ojCJz&=@!73uc)UF^E*PsRvj}{P|qLZ+XTD`ulDdZsYBOd zmwnE1zkMG}J;i@3bV{(Nmv1zaiDgQS{e-02&hnKM-s$11uxM*I`Bo^d7V9Yjm%`8) zK8=pSH)r@uSol(V`7ea=AlI*Gr267n{!99Nf;6#QsgR>&lD)o4@zxZ*sVGGyXsxT< zXP#J9?SC8)EfcsO;M3Kw&+$?LKlh5x^I`}f2e!8FUfs`Bk72L)ZH+U;e zgP5EAyEGGCyUEM&YfZh$Pg)#uOpq>DUM9zU1<&5*Q`FX5_LiYZXua2N~YVv)a JP9y4N@?TDZoxuPA diff --git a/substrate/frame/revive/rpc/src/main.rs b/substrate/frame/revive/rpc/src/main.rs index 06e1d2a0de68..f03d3321fb74 100644 --- a/substrate/frame/revive/rpc/src/main.rs +++ b/substrate/frame/revive/rpc/src/main.rs @@ -43,7 +43,7 @@ async fn main() -> anyhow::Result<()> { let CliCommand { url, node_url } = CliCommand::parse(); init_tracing(); - let client = Client::from_url(&node_url).await.unwrap(); + let client = Client::from_url(&node_url).await?; let mut updates = client.updates.clone(); let server_addr = run_server(client, &url).await?; From 595e66a982ec30c355bfd56c25dd4f5a6a81c2b5 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Mon, 7 Oct 2024 22:59:11 +0200 Subject: [PATCH 03/37] fixes --- Cargo.lock | 1 + substrate/bin/node/cli/Cargo.toml | 1 + substrate/bin/node/cli/src/chain_spec.rs | 16 +++++++- substrate/frame/revive/rpc/Cargo.toml | 3 +- substrate/frame/revive/rpc/examples/deploy.rs | 24 +++++++++--- .../frame/revive/rpc/examples/transfer.rs | 4 +- substrate/frame/revive/rpc/src/example.rs | 38 ++++--------------- 7 files changed, 47 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb89ecdfff11..7dc93f867d56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23565,6 +23565,7 @@ dependencies = [ "soketto 0.8.0", "staging-node-inspect", "substrate-cli-test-utils", + "subxt-signer", "tempfile", "tokio", "tokio-util", diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 6e734a723cd3..65c98bac5c38 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -46,6 +46,7 @@ futures = { workspace = true } log = { workspace = true, default-features = true } rand = { workspace = true, default-features = true } serde_json = { workspace = true, default-features = true } +subxt-signer = { workspace = true, features = ["unstable-eth"] } # The Polkadot-SDK: polkadot-sdk = { features = ["node"], workspace = true, default-features = true } diff --git a/substrate/bin/node/cli/src/chain_spec.rs b/substrate/bin/node/cli/src/chain_spec.rs index e0cad10c6f9c..722c3e41fdf0 100644 --- a/substrate/bin/node/cli/src/chain_spec.rs +++ b/substrate/bin/node/cli/src/chain_spec.rs @@ -322,6 +322,12 @@ fn configure_accounts( get_account_id_from_seed::("Dave//stash"), get_account_id_from_seed::("Eve//stash"), get_account_id_from_seed::("Ferdie//stash"), + eth_account(subxt_signer::eth::dev::alith()), + eth_account(subxt_signer::eth::dev::baltathar()), + eth_account(subxt_signer::eth::dev::charleth()), + eth_account(subxt_signer::eth::dev::dorothy()), + eth_account(subxt_signer::eth::dev::ethan()), + eth_account(subxt_signer::eth::dev::faith()), ] }); // endow all authorities and nominators. @@ -450,10 +456,18 @@ fn development_config_genesis_json() -> serde_json::Value { fn props() -> Properties { let mut properties = Properties::new(); - properties.insert("tokenDecimals".to_string(), "12".into()); + properties.insert("tokenDecimals".to_string(), 12.into()); properties } +use crate::chain_spec::sp_runtime::AccountId32; +fn eth_account(from: subxt_signer::eth::Keypair) -> AccountId32 { + let mut account_id = AccountId32::new([0xEE; 32]); + >::as_mut(&mut account_id)[..20] + .copy_from_slice(&from.account_id().0); + account_id +} + /// Development config (single validator Alice). pub fn development_config() -> ChainSpec { ChainSpec::builder(wasm_binary_unwrap(), Default::default()) diff --git a/substrate/frame/revive/rpc/Cargo.toml b/substrate/frame/revive/rpc/Cargo.toml index dbb84af54446..a54cdc4f9c0b 100644 --- a/substrate/frame/revive/rpc/Cargo.toml +++ b/substrate/frame/revive/rpc/Cargo.toml @@ -52,7 +52,8 @@ sp-runtime = { workspace = true, default-features = true } tower.workspace = true tower-http = { workspace = true, features = ["full"] } hyper.workspace = true -subxt-signer = { workspace = true, optional = true } + +subxt-signer = { workspace = true, optional = true, features = ["unstable-eth"] } hex = { workspace = true, optional = true } hex-literal = { workspace = true, optional = true } scale-info = { workspace = true } diff --git a/substrate/frame/revive/rpc/examples/deploy.rs b/substrate/frame/revive/rpc/examples/deploy.rs index b75964fc424e..14d72b804d6e 100644 --- a/substrate/frame/revive/rpc/examples/deploy.rs +++ b/substrate/frame/revive/rpc/examples/deploy.rs @@ -1,11 +1,11 @@ use codec::Encode; -use eth_rpc::{example::Account, EthRpcClient, ReceiptInfo}; use jsonrpsee::http_client::HttpClientBuilder; -use polkadot_sdk::pallet_revive::{ +use pallet_revive::{ create1, - evm::{BlockTag, Bytes, U256}, + evm::{BlockTag, Bytes, ReceiptInfo, U256}, EthInstantiateInput, }; +use pallet_revive_eth_rpc::{example::Account, EthRpcClient}; static DUMMY_BYTES: &[u8] = include_bytes!("./dummy.polkavm"); @@ -26,7 +26,14 @@ async fn main() -> anyhow::Result<()> { let hash = account.send_transaction(&client, U256::zero(), input.into(), None).await?; println!("Deploy Tx hash: {hash:?}"); - tokio::time::sleep(std::time::Duration::from_secs(2)).await; + for _ in 0..6 { + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + let receipt = client.get_transaction_receipt(hash).await?; + if receipt.is_some() { + break; + } + } + let ReceiptInfo { block_number, gas_used, contract_address, .. } = client.get_transaction_receipt(hash).await?.unwrap(); println!("Receipt received: "); @@ -46,7 +53,14 @@ async fn main() -> anyhow::Result<()> { .await?; println!("Contract call tx hash: {hash:?}"); - tokio::time::sleep(std::time::Duration::from_secs(2)).await; + + for _ in 0..6 { + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + let receipt = client.get_transaction_receipt(hash).await?; + if receipt.is_some() { + break + } + } let ReceiptInfo { block_number, gas_used, to, .. } = client.get_transaction_receipt(hash).await?.unwrap(); diff --git a/substrate/frame/revive/rpc/examples/transfer.rs b/substrate/frame/revive/rpc/examples/transfer.rs index f363ca09dc43..9e1b615022a5 100644 --- a/substrate/frame/revive/rpc/examples/transfer.rs +++ b/substrate/frame/revive/rpc/examples/transfer.rs @@ -1,7 +1,7 @@ -use eth_rpc::{example::Account, EthRpcClient}; use hex_literal::hex; use jsonrpsee::http_client::HttpClientBuilder; -use polkadot_sdk::pallet_revive::evm::{BlockTag, Bytes, H160}; +use pallet_revive::evm::{BlockTag, Bytes, H160}; +use pallet_revive_eth_rpc::{example::Account, EthRpcClient}; #[tokio::main] async fn main() -> anyhow::Result<()> { diff --git a/substrate/frame/revive/rpc/src/example.rs b/substrate/frame/revive/rpc/src/example.rs index d1c39aa95d23..1aa9b2f9b108 100644 --- a/substrate/frame/revive/rpc/src/example.rs +++ b/substrate/frame/revive/rpc/src/example.rs @@ -1,58 +1,34 @@ //! Example utilities #![cfg(feature = "example")] +use crate::EthRpcClient; use anyhow::Context; use jsonrpsee::http_client::HttpClient; use pallet_revive::evm::{ - rlp::*, BlockTag, Bytes, EthRpcClient, GenericTransaction, TransactionLegacySigned, + rlp::*, BlockTag, Bytes, GenericTransaction, TransactionLegacySigned, TransactionLegacyUnsigned, H160, H256, U256, }; -use secp256k1::{Message, PublicKey, Secp256k1, SecretKey}; -use sp_core::keccak_256; -use std::str::FromStr; /// A simple account that can sign transactions -pub struct Account { - /// The secret key of the account - sk: SecretKey, -} +pub struct Account(subxt_signer::eth::Keypair); impl Default for Account { fn default() -> Self { - Account { - sk: SecretKey::from_str( - "a872f6cbd25a0e04a08b1e21098017a9e6194d101d75e13111f71410c59cd57f", - ) - .unwrap(), - } + Self(subxt_signer::eth::dev::alith()) } } impl Account { - /// Create an account from a keypair. - pub fn from_keypair(pair: &subxt_signer::ecdsa::Keypair) -> Self { - let sb = pair.0.secret_key().secret_bytes(); - Account { sk: SecretKey::from_slice(&sb).unwrap() } - } - /// Get the [`H160`] address of the account. pub fn address(&self) -> H160 { - let pub_key = - PublicKey::from_secret_key(&Secp256k1::new(), &self.sk).serialize_uncompressed(); - let hash = keccak_256(&pub_key[1..]); - H160::from_slice(&hash[12..]) + H160::from_slice(&self.0.account_id().as_ref()) } /// Sign a transaction. pub fn sign_transaction(&self, tx: TransactionLegacyUnsigned) -> TransactionLegacySigned { let rlp_encoded = tx.rlp_bytes(); - let tx_hash = keccak_256(&rlp_encoded); - let secp = Secp256k1::new(); - let msg = Message::from_digest(tx_hash); - let sig = secp.sign_ecdsa_recoverable(&msg, &self.sk); - let (recovery_id, sig) = sig.serialize_compact(); - let sig = sig.into_iter().chain([recovery_id.to_i32() as u8]).collect::>(); - TransactionLegacySigned::from(tx, &sig.try_into().unwrap()) + let signature = self.0.sign(&rlp_encoded); + TransactionLegacySigned::from(tx, signature.as_ref()) } /// Send a transaction. From 96fa31d72c761f05a5cf8a9b042995cea9d134ab Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 8 Oct 2024 08:51:41 +0200 Subject: [PATCH 04/37] wip --- Cargo.lock | 2 ++ substrate/bin/node/runtime/Cargo.toml | 1 + substrate/bin/node/runtime/src/lib.rs | 5 ++++- substrate/frame/revive/rpc/src/example.rs | 2 ++ substrate/frame/transaction-payment/Cargo.toml | 1 + substrate/frame/transaction-payment/src/lib.rs | 1 + 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 7dc93f867d56..864151895231 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8548,6 +8548,7 @@ dependencies = [ "primitive-types 0.13.1", "scale-info", "serde_json", + "sp-debug-derive 14.0.0", "static_assertions", "substrate-wasm-builder", ] @@ -12986,6 +12987,7 @@ version = "28.0.0" dependencies = [ "frame-support", "frame-system", + "log", "pallet-balances", "parity-scale-codec", "scale-info", diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index 6310e16d5a14..d389247bb872 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -27,6 +27,7 @@ scale-info = { features = ["derive", "serde"], workspace = true } static_assertions = { workspace = true, default-features = true } log = { workspace = true } serde_json = { features = ["alloc", "arbitrary_precision"], workspace = true } +sp-debug-derive = { workspace = true, features = ["force-debug"] } # pallet-asset-conversion: turn on "num-traits" feature primitive-types = { features = ["codec", "num-traits", "scale-info"], workspace = true } diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index e9084af92566..61b353e981c6 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -3065,7 +3065,10 @@ impl_runtime_apis! { storage_deposit_limit.unwrap_or(u128::MAX), pallet_revive::DebugInfo::UnsafeDebug, pallet_revive::CollectEvents::UnsafeCollect, - ).map(pallet_transaction_payment::Pallet::::compute_fee) + ).map(|len, info, tip| { + log::info!(target: "evm", "compute_fee: len: {}, info: {:?}, tip: {:?}", len, info, tip); + pallet_transaction_payment::Pallet::::compute_fee(len, info, tip) + }) } fn call( diff --git a/substrate/frame/revive/rpc/src/example.rs b/substrate/frame/revive/rpc/src/example.rs index 1aa9b2f9b108..c9613f188261 100644 --- a/substrate/frame/revive/rpc/src/example.rs +++ b/substrate/frame/revive/rpc/src/example.rs @@ -80,6 +80,8 @@ impl Account { let tx = self.sign_transaction(unsigned_tx.clone()); let bytes = tx.rlp_bytes().to_vec(); + println!("Encode transaction len: {:?}", bytes.len()); + let hash = client .send_raw_transaction(bytes.clone().into()) .await diff --git a/substrate/frame/transaction-payment/Cargo.toml b/substrate/frame/transaction-payment/Cargo.toml index 4161a97f3cde..190d2de61351 100644 --- a/substrate/frame/transaction-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/Cargo.toml @@ -26,6 +26,7 @@ frame-system = { workspace = true } sp-core = { workspace = true } sp-io = { workspace = true } sp-runtime = { workspace = true } +log = { workspace = true } [dev-dependencies] serde_json = { workspace = true, default-features = true } diff --git a/substrate/frame/transaction-payment/src/lib.rs b/substrate/frame/transaction-payment/src/lib.rs index c17ab393b5d3..7e524f1d606f 100644 --- a/substrate/frame/transaction-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/src/lib.rs @@ -577,6 +577,7 @@ impl Pallet { where T::RuntimeCall: Dispatchable, { + log::info!(target: "evm", "compute_fee: len: {len:?}, info: {info:?}, tip: {tip:?}"); Self::compute_fee_details(len, info, tip).final_fee() } From 551cd3daea1e84ef4ba2f50443a3b28f6c9214e0 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 8 Oct 2024 17:19:00 +0200 Subject: [PATCH 05/37] update rpc stuff --- substrate/frame/revive/rpc/examples/deploy.rs | 29 +++++------------- .../frame/revive/rpc/examples/transfer.rs | 14 ++++++--- substrate/frame/revive/rpc/kitchensink.scale | Bin 651612 -> 651621 bytes substrate/frame/revive/rpc/metadata.scale | Bin 57102 -> 0 bytes substrate/frame/revive/rpc/src/client.rs | 8 ++--- substrate/frame/revive/rpc/src/example.rs | 17 ++++++++-- substrate/frame/revive/rpc/src/lib.rs | 4 +-- .../frame/revive/rpc/src/subxt_client.rs | 2 +- 8 files changed, 36 insertions(+), 38 deletions(-) delete mode 100644 substrate/frame/revive/rpc/metadata.scale diff --git a/substrate/frame/revive/rpc/examples/deploy.rs b/substrate/frame/revive/rpc/examples/deploy.rs index 14d72b804d6e..3b030c5f21bb 100644 --- a/substrate/frame/revive/rpc/examples/deploy.rs +++ b/substrate/frame/revive/rpc/examples/deploy.rs @@ -5,7 +5,10 @@ use pallet_revive::{ evm::{BlockTag, Bytes, ReceiptInfo, U256}, EthInstantiateInput, }; -use pallet_revive_eth_rpc::{example::Account, EthRpcClient}; +use pallet_revive_eth_rpc::{ + example::{wait_for_receipt, Account}, + EthRpcClient, +}; static DUMMY_BYTES: &[u8] = include_bytes!("./dummy.polkavm"); @@ -24,18 +27,10 @@ async fn main() -> anyhow::Result<()> { let input = input.encode(); let nonce = client.get_transaction_count(account.address(), BlockTag::Latest.into()).await?; let hash = account.send_transaction(&client, U256::zero(), input.into(), None).await?; - println!("Deploy Tx hash: {hash:?}"); - - for _ in 0..6 { - tokio::time::sleep(std::time::Duration::from_secs(2)).await; - let receipt = client.get_transaction_receipt(hash).await?; - if receipt.is_some() { - break; - } - } + println!("Deploy Tx hash: {hash:?}"); let ReceiptInfo { block_number, gas_used, contract_address, .. } = - client.get_transaction_receipt(hash).await?.unwrap(); + wait_for_receipt(&client, hash).await?; println!("Receipt received: "); println!("Block number: {block_number}"); println!("Gas used: {gas_used}"); @@ -53,17 +48,7 @@ async fn main() -> anyhow::Result<()> { .await?; println!("Contract call tx hash: {hash:?}"); - - for _ in 0..6 { - tokio::time::sleep(std::time::Duration::from_secs(2)).await; - let receipt = client.get_transaction_receipt(hash).await?; - if receipt.is_some() { - break - } - } - - let ReceiptInfo { block_number, gas_used, to, .. } = - client.get_transaction_receipt(hash).await?.unwrap(); + let ReceiptInfo { block_number, gas_used, to, .. } = wait_for_receipt(&client, hash).await?; println!("Receipt received: "); println!("Block number: {block_number}"); println!("Gas used: {gas_used}"); diff --git a/substrate/frame/revive/rpc/examples/transfer.rs b/substrate/frame/revive/rpc/examples/transfer.rs index 9e1b615022a5..e89ca0e4c86a 100644 --- a/substrate/frame/revive/rpc/examples/transfer.rs +++ b/substrate/frame/revive/rpc/examples/transfer.rs @@ -1,7 +1,10 @@ use hex_literal::hex; use jsonrpsee::http_client::HttpClientBuilder; -use pallet_revive::evm::{BlockTag, Bytes, H160}; -use pallet_revive_eth_rpc::{example::Account, EthRpcClient}; +use pallet_revive::evm::{BlockTag, Bytes, ReceiptInfo, H160}; +use pallet_revive_eth_rpc::{ + example::{wait_for_receipt, Account}, + EthRpcClient, +}; #[tokio::main] async fn main() -> anyhow::Result<()> { @@ -20,9 +23,10 @@ async fn main() -> anyhow::Result<()> { let hash = account.send_transaction(&client, value, Bytes::default(), to).await?; println!("Transaction hash: {hash:?}"); - tokio::time::sleep(std::time::Duration::from_secs(2)).await; - let receipt = client.get_transaction_receipt(hash).await; - println!("Receipt: {receipt:?}"); + let ReceiptInfo { block_number, gas_used, .. } = wait_for_receipt(&client, hash).await?; + println!("Receipt received: "); + println!("Block number: {block_number}"); + println!("Gas used: {gas_used}"); let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?; println!("Account balance: {:?}", balance); diff --git a/substrate/frame/revive/rpc/kitchensink.scale b/substrate/frame/revive/rpc/kitchensink.scale index ceb4c6ba3ea2df0d0183637825654c3b7a0a6e18..86f6ce6ccdac59f2bcd930c8415f28c297f15f59 100644 GIT binary patch delta 42 xcmccfNd4&}^@bM47N!>F7M2#)7Pc+yZdazq&0$q)kH5kW#2nk>uWF7M2#)7Pc+yZdVuu+5@hz12M<;fGeD$vH(O84&nd+ diff --git a/substrate/frame/revive/rpc/metadata.scale b/substrate/frame/revive/rpc/metadata.scale deleted file mode 100644 index ffd5662a46e848ca6ce0ef9c6a2d88d03bf18705..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57102 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 diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 9e8db2c72f01..203fab37ffb1 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -4,10 +4,7 @@ #![allow(unused_imports, unused_variables)] use crate::{ rlp, - subxt_client::{ - revive::calls::types::EthTransact, - runtime_types::{frame_system::EventRecord, revive_runtime::RuntimeEvent}, - }, + subxt_client::{revive::calls::types::EthTransact, runtime_types::frame_system::EventRecord}, TransactionLegacySigned, LOG_TARGET, }; use codec::{Decode, Encode}; @@ -138,7 +135,8 @@ pub enum ClientError { // Convert a `ClientError` to an RPC `ErrorObjectOwned`. impl From for ErrorObjectOwned { - fn from(_value: ClientError) -> Self { + fn from(value: ClientError) -> Self { + log::debug!(target: LOG_TARGET, "ClientError: {value:?}"); ErrorObjectOwned::owned::<()>( ErrorCode::InternalError.code(), ErrorCode::InternalError.message(), diff --git a/substrate/frame/revive/rpc/src/example.rs b/substrate/frame/revive/rpc/src/example.rs index c9613f188261..e6787cef24f6 100644 --- a/substrate/frame/revive/rpc/src/example.rs +++ b/substrate/frame/revive/rpc/src/example.rs @@ -1,7 +1,7 @@ //! Example utilities #![cfg(feature = "example")] -use crate::EthRpcClient; +use crate::{EthRpcClient, ReceiptInfo}; use anyhow::Context; use jsonrpsee::http_client::HttpClient; use pallet_revive::evm::{ @@ -18,6 +18,19 @@ impl Default for Account { } } +/// Wait for a transaction receipt. +pub async fn wait_for_receipt(client: &HttpClient, hash: H256) -> anyhow::Result { + for _ in 0..6 { + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + let receipt = client.get_transaction_receipt(hash).await?; + if let Some(receipt) = receipt { + return Ok(receipt) + } + } + + anyhow::bail!("Failed to get receipt") +} + impl Account { /// Get the [`H160`] address of the account. pub fn address(&self) -> H160 { @@ -80,8 +93,6 @@ impl Account { let tx = self.sign_transaction(unsigned_tx.clone()); let bytes = tx.rlp_bytes().to_vec(); - println!("Encode transaction len: {:?}", bytes.len()); - let hash = client .send_raw_transaction(bytes.clone().into()) .await diff --git a/substrate/frame/revive/rpc/src/lib.rs b/substrate/frame/revive/rpc/src/lib.rs index 5bbed3c3af09..0f830bba7c1a 100644 --- a/substrate/frame/revive/rpc/src/lib.rs +++ b/substrate/frame/revive/rpc/src/lib.rs @@ -124,12 +124,12 @@ impl EthRpcServer for EthRpcServerImpl { ) .await?; - let EthContractResult { kind, gas_limit, storage_deposit, .. } = dry_run; + let EthContractResult { transact_kind, gas_limit, storage_deposit, .. } = dry_run; let call = subxt_client::tx().revive().eth_transact( transaction.0, gas_limit.into(), storage_deposit, - kind.into(), + transact_kind.into(), ); let ext = self.client.tx().create_unsigned(&call).map_err(|err| ClientError::from(err))?; let hash = ext.submit().await.map_err(|err| EthRpcError::ClientError(err.into()))?; diff --git a/substrate/frame/revive/rpc/src/subxt_client.rs b/substrate/frame/revive/rpc/src/subxt_client.rs index eaff1b021f03..847de2f7efdf 100644 --- a/substrate/frame/revive/rpc/src/subxt_client.rs +++ b/substrate/frame/revive/rpc/src/subxt_client.rs @@ -2,7 +2,7 @@ use subxt::config::{signed_extensions, Config, PolkadotConfig}; #[subxt::subxt( - runtime_metadata_path = "metadata.scale", + runtime_metadata_path = "kitchensink.scale", substitute_type( path = "pallet_revive::primitives::EthContractResult", with = "::subxt::utils::Static<::pallet_revive::EthContractResult>" From 2a90e9b6ae67b108ce060c7cf03bb066f202bde5 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 8 Oct 2024 18:25:31 +0200 Subject: [PATCH 06/37] rlp encoding --- substrate/frame/revive/rpc/Cargo.toml | 3 ++- substrate/frame/revive/rpc/examples/deploy.rs | 6 ++---- substrate/frame/revive/rpc/src/client.rs | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/substrate/frame/revive/rpc/Cargo.toml b/substrate/frame/revive/rpc/Cargo.toml index a54cdc4f9c0b..c6b53ff4e89c 100644 --- a/substrate/frame/revive/rpc/Cargo.toml +++ b/substrate/frame/revive/rpc/Cargo.toml @@ -53,6 +53,7 @@ tower.workspace = true tower-http = { workspace = true, features = ["full"] } hyper.workspace = true +rlp = { workspace = true, optional = true } subxt-signer = { workspace = true, optional = true, features = ["unstable-eth"] } hex = { workspace = true, optional = true } hex-literal = { workspace = true, optional = true } @@ -62,7 +63,7 @@ env_logger = { workspace = true } [features] dev = [] -example = ["hex", "hex-literal", "secp256k1", "subxt-signer"] +example = ["hex", "hex-literal", "secp256k1", "subxt-signer", "rlp"] [dev-dependencies] hex-literal.workspace = true diff --git a/substrate/frame/revive/rpc/examples/deploy.rs b/substrate/frame/revive/rpc/examples/deploy.rs index 3b030c5f21bb..cb0579d7e978 100644 --- a/substrate/frame/revive/rpc/examples/deploy.rs +++ b/substrate/frame/revive/rpc/examples/deploy.rs @@ -1,9 +1,7 @@ -use codec::Encode; use jsonrpsee::http_client::HttpClientBuilder; use pallet_revive::{ create1, - evm::{BlockTag, Bytes, ReceiptInfo, U256}, - EthInstantiateInput, + evm::{BlockTag, Bytes, EthInstantiateInput, ReceiptInfo, U256}, }; use pallet_revive_eth_rpc::{ example::{wait_for_receipt, Account}, @@ -24,7 +22,7 @@ async fn main() -> anyhow::Result<()> { println!("\n\n=== Deploying contract ===\n\n"); - let input = input.encode(); + let input = rlp::encode(&input).to_vec(); let nonce = client.get_transaction_count(account.address(), BlockTag::Latest.into()).await?; let hash = account.send_transaction(&client, U256::zero(), input.into(), None).await?; diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 203fab37ffb1..f75d157a1f78 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -13,10 +13,10 @@ use jsonrpsee::types::{ErrorCode, ErrorObjectOwned}; use pallet_revive::{ create1, evm::{ - Block, BlockNumberOrTag, BlockNumberOrTagOrHash, Bytes256, GenericTransaction, ReceiptInfo, - TransactionSigned, H160, H256, U256, + Block, BlockNumberOrTag, BlockNumberOrTagOrHash, Bytes256, EthInstantiateInput, + GenericTransaction, ReceiptInfo, TransactionSigned, H160, H256, U256, }, - ContractResult, EthContractResult, EthInstantiateInput, + ContractResult, EthContractResult, }; use sp_runtime::traits::Hash; use sp_weights::Weight; From 4dede9c30160a9c151b106353ffeb4e3a86f4527 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 8 Oct 2024 19:30:02 +0200 Subject: [PATCH 07/37] Update --- Cargo.lock | 1 + substrate/frame/revive/rpc/examples/deploy.rs | 16 ++++++++-------- substrate/frame/revive/rpc/examples/transfer.rs | 6 +++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 864151895231..3ae156c6295d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12535,6 +12535,7 @@ dependencies = [ "log", "pallet-revive", "parity-scale-codec", + "rlp", "scale-info", "secp256k1", "serde_json", diff --git a/substrate/frame/revive/rpc/examples/deploy.rs b/substrate/frame/revive/rpc/examples/deploy.rs index cb0579d7e978..bae3697e96b5 100644 --- a/substrate/frame/revive/rpc/examples/deploy.rs +++ b/substrate/frame/revive/rpc/examples/deploy.rs @@ -29,10 +29,10 @@ async fn main() -> anyhow::Result<()> { println!("Deploy Tx hash: {hash:?}"); let ReceiptInfo { block_number, gas_used, contract_address, .. } = wait_for_receipt(&client, hash).await?; - println!("Receipt received: "); - println!("Block number: {block_number}"); - println!("Gas used: {gas_used}"); - println!("Contract address: {contract_address:?}"); + println!("Receipt:"); + println!("- Block number: {block_number}"); + println!("- Gas used: {gas_used}"); + println!("- Contract address: {contract_address:?}"); if std::env::var("SKIP_CALL").is_ok() { return Ok(()) @@ -47,9 +47,9 @@ async fn main() -> anyhow::Result<()> { println!("Contract call tx hash: {hash:?}"); let ReceiptInfo { block_number, gas_used, to, .. } = wait_for_receipt(&client, hash).await?; - println!("Receipt received: "); - println!("Block number: {block_number}"); - println!("Gas used: {gas_used}"); - println!("To: {to:?}"); + println!("Receipt:"); + println!("- Block number: {block_number}"); + println!("- Gas used: {gas_used}"); + println!("- To: {to:?}"); Ok(()) } diff --git a/substrate/frame/revive/rpc/examples/transfer.rs b/substrate/frame/revive/rpc/examples/transfer.rs index e89ca0e4c86a..634131f4da92 100644 --- a/substrate/frame/revive/rpc/examples/transfer.rs +++ b/substrate/frame/revive/rpc/examples/transfer.rs @@ -24,9 +24,9 @@ async fn main() -> anyhow::Result<()> { println!("Transaction hash: {hash:?}"); let ReceiptInfo { block_number, gas_used, .. } = wait_for_receipt(&client, hash).await?; - println!("Receipt received: "); - println!("Block number: {block_number}"); - println!("Gas used: {gas_used}"); + println!("Receipt: "); + println!("- Block number: {block_number}"); + println!("- Gas used: {gas_used}"); let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?; println!("Account balance: {:?}", balance); From c2609faf0e979d2df364dd3a8e1a6691b02e8cfc Mon Sep 17 00:00:00 2001 From: pgherveou Date: Wed, 9 Oct 2024 09:52:39 +0200 Subject: [PATCH 08/37] add js stuff --- substrate/frame/revive/rpc/demo/package.json | 24 + .../frame/revive/rpc/demo/src/global.d.ts | 7 + .../frame/revive/rpc/demo/src/index.html | 28 + substrate/frame/revive/rpc/demo/src/main.ts | 102 ++++ substrate/frame/revive/rpc/demo/tsconfig.json | 13 + .../frame/revive/rpc/demo/vite.config.ts | 10 + substrate/frame/revive/rpc/demo/yarn.lock | 535 ++++++++++++++++++ .../frame/revive/rpc/examples/transfer.rs | 30 +- substrate/frame/revive/rpc/src/example.rs | 6 + 9 files changed, 742 insertions(+), 13 deletions(-) create mode 100644 substrate/frame/revive/rpc/demo/package.json create mode 100644 substrate/frame/revive/rpc/demo/src/global.d.ts create mode 100644 substrate/frame/revive/rpc/demo/src/index.html create mode 100644 substrate/frame/revive/rpc/demo/src/main.ts create mode 100644 substrate/frame/revive/rpc/demo/tsconfig.json create mode 100644 substrate/frame/revive/rpc/demo/vite.config.ts create mode 100644 substrate/frame/revive/rpc/demo/yarn.lock diff --git a/substrate/frame/revive/rpc/demo/package.json b/substrate/frame/revive/rpc/demo/package.json new file mode 100644 index 000000000000..a2e7e432013e --- /dev/null +++ b/substrate/frame/revive/rpc/demo/package.json @@ -0,0 +1,24 @@ +{ + "name": "metamask-deploy", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "vite", + "build": "vite build", + "prettier": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@polkadot/types": "^12.2.1", + "@polkadot/util": "^13.0.2", + "ethers": "^6.13.1" + }, + "devDependencies": { + "@types/node": "^14.14.6", + "prettier": "^3.3.3", + "typescript": "^4.1.2", + "vite": "^2.5.0" + } +} diff --git a/substrate/frame/revive/rpc/demo/src/global.d.ts b/substrate/frame/revive/rpc/demo/src/global.d.ts new file mode 100644 index 000000000000..1500e4142af7 --- /dev/null +++ b/substrate/frame/revive/rpc/demo/src/global.d.ts @@ -0,0 +1,7 @@ +import { MetaMaskInpageProvider } from '@metamask/providers'; + +declare global { + interface Window { + ethereum?: MetaMaskInpageProvider; + } +} diff --git a/substrate/frame/revive/rpc/demo/src/index.html b/substrate/frame/revive/rpc/demo/src/index.html new file mode 100644 index 000000000000..c479742690d6 --- /dev/null +++ b/substrate/frame/revive/rpc/demo/src/index.html @@ -0,0 +1,28 @@ + + + + + + Deploy Contract with MetaMask + + + + + + + + + + + + + + + diff --git a/substrate/frame/revive/rpc/demo/src/main.ts b/substrate/frame/revive/rpc/demo/src/main.ts new file mode 100644 index 000000000000..564f16328e73 --- /dev/null +++ b/substrate/frame/revive/rpc/demo/src/main.ts @@ -0,0 +1,102 @@ +import { BrowserProvider, Contract, ContractFactory, JsonRpcSigner, parseEther, encodeRlp, AddressLike } from 'ethers'; +import { hexToU8a } from '@polkadot/util'; + +document.addEventListener('DOMContentLoaded', async () => { + if (typeof window.ethereum == 'undefined') { + return console.log('MetaMask is not installed'); + } + + console.log('MetaMask is installed!'); + const provider = new BrowserProvider(window.ethereum); + + console.log('Getting signer...'); + let signer: JsonRpcSigner; + try { + signer = await provider.getSigner(); + console.log(`Signer: ${signer.address}`); + } catch (e) { + console.error('Failed to get signer', e); + return; + } + + console.log('Getting block number...'); + try { + const blockNumber = await provider.getBlockNumber(); + console.log(`Block number: ${blockNumber}`); + } catch (e) { + console.error('Failed to get block number', e); + return; + } + + const nonce = await signer.getNonce(); + console.log(`Nonce: ${nonce}`); + + document.getElementById('transferButton')?.addEventListener('click', async () => { + const address = (document.getElementById('transferInput') as HTMLInputElement).value; + await transfer(address); + }); + + document.getElementById('deployButton')?.addEventListener('click', async () => { + await deploy(); + }); + document.getElementById('deployAndCallButton')?.addEventListener('click', async () => { + const nonce = await signer.getNonce(); + console.log(`deploy with nonce: ${nonce}`); + + const address = await deploy(); + if (address) { + const nonce = await signer.getNonce(); + console.log(`call with nonce: ${nonce}`); + await call(address); + } + + }); + document.getElementById('callButton')?.addEventListener('click', async () => { + const address = (document.getElementById('callInput') as HTMLInputElement).value; + await call(address); + }); + + async function deploy() { + console.log('Deploying contract...'); + const code = hexToU8a('0x50564d0001010424009000022363616c6cdeadbeef63616c6c5f6e657665726465706c6f797365616c5f72657475726e041001000000007365616c5f72657475726e051b03000a63616c6c5f6e6576657204066465706c6f79060463616c6c062c06011f000406081b1c06100408130013000211fc03100408040001040904040706100a05004e13005129a4b800'); + const args = new Uint8Array() + const bytecode = encodeRlp([ code, args ]); + const contractFactory = new ContractFactory([], bytecode, signer); + + try { + const contract = await contractFactory.deploy(); + await contract.waitForDeployment(); + const address = await contract.getAddress(); + console.log(`Contract deployed: ${address}`); + return address; + } catch (e) { + console.error('Failed to deploy contract', e); + return; + } + } + + async function call(address: string) { + const abi = ['function getValue() view returns (uint256)', 'function setValue(uint256 _value)']; + + const contract = new Contract(address, abi, signer); + const tx = await contract.setValue(42); + + console.log('Transaction hash:', tx.hash); + } + + async function transfer(to: AddressLike) { + console.log(`transferring 1 DOT to ${to}...`); + try { + const tx = await signer.sendTransaction({ + to, + value: parseEther('1.0'), + }); + + const receipt = await tx.wait(); + console.log(`Transaction hash: ${receipt?.hash}`); + } catch (e) { + console.error('Failed to send transaction', e); + return; + } + } +}); diff --git a/substrate/frame/revive/rpc/demo/tsconfig.json b/substrate/frame/revive/rpc/demo/tsconfig.json new file mode 100644 index 000000000000..19f43a33fa9f --- /dev/null +++ b/substrate/frame/revive/rpc/demo/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx" + }, + "include": ["src"] +} diff --git a/substrate/frame/revive/rpc/demo/vite.config.ts b/substrate/frame/revive/rpc/demo/vite.config.ts new file mode 100644 index 000000000000..825b100e3da2 --- /dev/null +++ b/substrate/frame/revive/rpc/demo/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; + +export default defineConfig({ + root: 'src', + build: { + sourcemap: true, + target: 'esnext', + outDir: '../dist', + }, +}); diff --git a/substrate/frame/revive/rpc/demo/yarn.lock b/substrate/frame/revive/rpc/demo/yarn.lock new file mode 100644 index 000000000000..744071a85412 --- /dev/null +++ b/substrate/frame/revive/rpc/demo/yarn.lock @@ -0,0 +1,535 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/curves@^1.3.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.6.0.tgz#be5296ebcd5a1730fccea4786d420f87abfeb40b" + integrity sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ== + dependencies: + "@noble/hashes" "1.5.0" + +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/hashes@1.5.0", "@noble/hashes@^1.3.3": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== + +"@polkadot/keyring@^13.0.2": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-13.1.1.tgz#14b85d4e73ebfa8ccb0fadcdee127e102624dc11" + integrity sha512-Wm+9gn946GIPjGzvueObLGBBS9s541HE6mvKdWGEmPFMzH93ESN931RZlOd67my5MWryiSP05h5SHTp7bSaQTA== + dependencies: + "@polkadot/util" "13.1.1" + "@polkadot/util-crypto" "13.1.1" + tslib "^2.7.0" + +"@polkadot/networks@13.1.1": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-13.1.1.tgz#e1a05ef6f78ffc37272c6474df7b55244b311f9c" + integrity sha512-eEQ4+Mfl1xFtApeU5PdXZ2XBhxNSvUz9yW+YQVGUCkXRjWFbqNRsTOYWGd9uFbiAOXiiiXbtqfZpxSDzIm4XOg== + dependencies: + "@polkadot/util" "13.1.1" + "@substrate/ss58-registry" "^1.50.0" + tslib "^2.7.0" + +"@polkadot/types-augment@12.4.2": + version "12.4.2" + resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-12.4.2.tgz#8b8e278f4cbecbdd586470d31c27576e06e87074" + integrity sha512-3fDCOy2BEMuAtMYl4crKg76bv/0pDNEuzpAzV4EBUMIlJwypmjy5sg3gUPCMcA+ckX3xb8DhkWU4ceUdS7T2KQ== + dependencies: + "@polkadot/types" "12.4.2" + "@polkadot/types-codec" "12.4.2" + "@polkadot/util" "^13.0.2" + tslib "^2.6.3" + +"@polkadot/types-codec@12.4.2": + version "12.4.2" + resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-12.4.2.tgz#aa601ddbbe4bb28ef751e4565bd87037dee9a49b" + integrity sha512-DiPGRFWtVMepD9i05eC3orSbGtpN7un/pXOrXu0oriU+oxLkpvZH68ZsPNtJhKdQy03cAYtvB8elJOFJZYqoqQ== + dependencies: + "@polkadot/util" "^13.0.2" + "@polkadot/x-bigint" "^13.0.2" + tslib "^2.6.3" + +"@polkadot/types-create@12.4.2": + version "12.4.2" + resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-12.4.2.tgz#1113746ab92694c3402abc59feb3e3fcaf980997" + integrity sha512-nOpeAKZLdSqNMfzS3waQXgyPPaNt8rUHEmR5+WNv6c/Ke/vyf710wjxiTewfp0wpBgtdrimlgG4DLX1J9Ms1LA== + dependencies: + "@polkadot/types-codec" "12.4.2" + "@polkadot/util" "^13.0.2" + tslib "^2.6.3" + +"@polkadot/types@12.4.2", "@polkadot/types@^12.2.1": + version "12.4.2" + resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-12.4.2.tgz#948e0191b30c37f0d89b8e120174d6be31ed9f9d" + integrity sha512-ivYtt7hYcRvo69ULb1BJA9BE1uefijXcaR089Dzosr9+sMzvsB1yslNQReOq+Wzq6h6AQj4qex6qVqjWZE6Z4A== + dependencies: + "@polkadot/keyring" "^13.0.2" + "@polkadot/types-augment" "12.4.2" + "@polkadot/types-codec" "12.4.2" + "@polkadot/types-create" "12.4.2" + "@polkadot/util" "^13.0.2" + "@polkadot/util-crypto" "^13.0.2" + rxjs "^7.8.1" + tslib "^2.6.3" + +"@polkadot/util-crypto@13.1.1", "@polkadot/util-crypto@^13.0.2": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-13.1.1.tgz#26960046a9bd6b3b63dc9b006c1a24dc6391b875" + integrity sha512-FG68rrLPdfLcscEyH10vnGkakM4O2lqr71S3GDhgc9WXaS8y9jisLgMPg8jbMHiQBJ3iKYkmtPKiLBowRslj2w== + dependencies: + "@noble/curves" "^1.3.0" + "@noble/hashes" "^1.3.3" + "@polkadot/networks" "13.1.1" + "@polkadot/util" "13.1.1" + "@polkadot/wasm-crypto" "^7.3.2" + "@polkadot/wasm-util" "^7.3.2" + "@polkadot/x-bigint" "13.1.1" + "@polkadot/x-randomvalues" "13.1.1" + "@scure/base" "^1.1.7" + tslib "^2.7.0" + +"@polkadot/util@13.1.1", "@polkadot/util@^13.0.2": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-13.1.1.tgz#9cbf81e8c48e2ac549dbe2a40384624870016658" + integrity sha512-M4iQ5Um8tFdDmD7a96nPzfrEt+kxyWOqQDPqXyaax4QBnq/WCbq0jo8IO61uz55mdMQnGZvq8jd8uge4V6JzzQ== + dependencies: + "@polkadot/x-bigint" "13.1.1" + "@polkadot/x-global" "13.1.1" + "@polkadot/x-textdecoder" "13.1.1" + "@polkadot/x-textencoder" "13.1.1" + "@types/bn.js" "^5.1.5" + bn.js "^5.2.1" + tslib "^2.7.0" + +"@polkadot/wasm-bridge@7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-bridge/-/wasm-bridge-7.3.2.tgz#e1b01906b19e06cbca3d94f10f5666f2ae0baadc" + integrity sha512-AJEXChcf/nKXd5Q/YLEV5dXQMle3UNT7jcXYmIffZAo/KI394a+/24PaISyQjoNC0fkzS1Q8T5pnGGHmXiVz2g== + dependencies: + "@polkadot/wasm-util" "7.3.2" + tslib "^2.6.2" + +"@polkadot/wasm-crypto-asmjs@7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.3.2.tgz#c6d41bc4b48b5359d57a24ca3066d239f2d70a34" + integrity sha512-QP5eiUqUFur/2UoF2KKKYJcesc71fXhQFLT3D4ZjG28Mfk2ZPI0QNRUfpcxVQmIUpV5USHg4geCBNuCYsMm20Q== + dependencies: + tslib "^2.6.2" + +"@polkadot/wasm-crypto-init@7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.3.2.tgz#7e1fe79ba978fb0a4a0f74a92d976299d38bc4b8" + integrity sha512-FPq73zGmvZtnuJaFV44brze3Lkrki3b4PebxCy9Fplw8nTmisKo9Xxtfew08r0njyYh+uiJRAxPCXadkC9sc8g== + dependencies: + "@polkadot/wasm-bridge" "7.3.2" + "@polkadot/wasm-crypto-asmjs" "7.3.2" + "@polkadot/wasm-crypto-wasm" "7.3.2" + "@polkadot/wasm-util" "7.3.2" + tslib "^2.6.2" + +"@polkadot/wasm-crypto-wasm@7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.3.2.tgz#44e08ed5cf6499ce4a3aa7247071a5d01f6a74f4" + integrity sha512-15wd0EMv9IXs5Abp1ZKpKKAVyZPhATIAHfKsyoWCEFDLSOA0/K0QGOxzrAlsrdUkiKZOq7uzSIgIDgW8okx2Mw== + dependencies: + "@polkadot/wasm-util" "7.3.2" + tslib "^2.6.2" + +"@polkadot/wasm-crypto@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-7.3.2.tgz#61bbcd9e591500705c8c591e6aff7654bdc8afc9" + integrity sha512-+neIDLSJ6jjVXsjyZ5oLSv16oIpwp+PxFqTUaZdZDoA2EyFRQB8pP7+qLsMNk+WJuhuJ4qXil/7XiOnZYZ+wxw== + dependencies: + "@polkadot/wasm-bridge" "7.3.2" + "@polkadot/wasm-crypto-asmjs" "7.3.2" + "@polkadot/wasm-crypto-init" "7.3.2" + "@polkadot/wasm-crypto-wasm" "7.3.2" + "@polkadot/wasm-util" "7.3.2" + tslib "^2.6.2" + +"@polkadot/wasm-util@7.3.2", "@polkadot/wasm-util@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@polkadot/wasm-util/-/wasm-util-7.3.2.tgz#4fe6370d2b029679b41a5c02cd7ebf42f9b28de1" + integrity sha512-bmD+Dxo1lTZyZNxbyPE380wd82QsX+43mgCm40boyKrRppXEyQmWT98v/Poc7chLuskYb6X8IQ6lvvK2bGR4Tg== + dependencies: + tslib "^2.6.2" + +"@polkadot/x-bigint@13.1.1", "@polkadot/x-bigint@^13.0.2": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-13.1.1.tgz#1a9036c9529ce15deab808bee7333bcbd3ab0078" + integrity sha512-Cq4Y6fd9UWtRBZz8RX2tWEBL1IFwUtY6cL8p6HC9yhZtUR6OPjKZe6RIZQa9gSOoIuqZWd6PmtvSNGVH32yfkQ== + dependencies: + "@polkadot/x-global" "13.1.1" + tslib "^2.7.0" + +"@polkadot/x-global@13.1.1": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-13.1.1.tgz#1db0c16e45a20eddf682c98b1d3487619203c8a9" + integrity sha512-DViIMmmEs29Qlsp058VTg2Mn7e3/CpGazNnKJrsBa0o1Ptxl13/4Z0fjqCpNi2GB+kaOsnREzxUORrHcU+PqcQ== + dependencies: + tslib "^2.7.0" + +"@polkadot/x-randomvalues@13.1.1": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-13.1.1.tgz#e3fc6e77cdfe6f345fca7433dd92a914807a7e4f" + integrity sha512-cXj4omwbgzQQSiBtV1ZBw+XhJUU3iz/DS6ghUnGllSZEK+fGqiyaNgeFQzDY0tKjm6kYaDpvtOHR3mHsbzDuTg== + dependencies: + "@polkadot/x-global" "13.1.1" + tslib "^2.7.0" + +"@polkadot/x-textdecoder@13.1.1": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-13.1.1.tgz#305e9a1be38aa435942bc2a73b088a2ca1c1c89b" + integrity sha512-LpZ9KYc6HdBH+i86bCmun4g4GWMiWN/1Pzs0hNdanlQMfqp3UGzl1Dqp0nozMvjWAlvyG7ip235VgNMd8HEbqg== + dependencies: + "@polkadot/x-global" "13.1.1" + tslib "^2.7.0" + +"@polkadot/x-textencoder@13.1.1": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-13.1.1.tgz#2588c57c1fae68493a5588a156313d25b91a577e" + integrity sha512-w1mT15B9ptN5CJNgN/A0CmBqD5y9OePjBdU6gmAd8KRhwXCF0MTBKcEZk1dHhXiXtX+28ULJWLrfefC5gxy69Q== + dependencies: + "@polkadot/x-global" "13.1.1" + tslib "^2.7.0" + +"@scure/base@^1.1.7": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" + integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== + +"@substrate/ss58-registry@^1.50.0": + version "1.50.0" + resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.50.0.tgz#2d2a3d060cd4eadd200e4538078461ba73e13d6d" + integrity sha512-mkmlMlcC+MSd9rA+PN8ljGAm5fVZskvVwkXIsbx4NFwaT8kt38r7e9cyDWscG3z2Zn40POviZvEMrJSk+r2SgQ== + +"@types/bn.js@^5.1.5": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "22.6.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.6.0.tgz#b604c9a628760221905c1b272fd6aee661f45042" + integrity sha512-QyR8d5bmq+eR72TwQDfujwShHMcIrWIYsaQFtXRE58MHPTEKUNxjxvl0yS0qPMds5xbSDWtp7ZpvGFtd7dfMdQ== + dependencies: + undici-types "~6.19.2" + +"@types/node@18.15.13": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + +"@types/node@^14.14.6": + version "14.18.63" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.63.tgz#1788fa8da838dbb5f9ea994b834278205db6ca2b" + integrity sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ== + +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + +bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== + +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== + +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== + +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== + +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== + +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== + +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== + +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== + +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== + +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== + +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== + +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== + +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== + +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== + +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== + +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== + +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== + +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== + +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== + +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== + +esbuild@^0.14.27: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== + optionalDependencies: + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" + +ethers@^6.13.1: + version "6.13.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe" + integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.17.1" + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== + dependencies: + hasown "^2.0.2" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + +postcss@^8.4.13: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + +prettier@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" + integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== + +resolve@^1.22.0: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +"rollup@>=2.59.0 <2.78.0": + version "2.77.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.3.tgz#8f00418d3a2740036e15deb653bed1a90ee0cc12" + integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== + optionalDependencies: + fsevents "~2.3.2" + +rxjs@^7.8.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +scale-codec@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/scale-codec/-/scale-codec-0.13.0.tgz#7c9842412e0e4fdab5f9f10b475e3fbd40fdb23f" + integrity sha512-HxLaGxglkZP7SwjCLZPMsWGKN8Q/h5bjIH9YLFRcsG3Fmh+qsCOZYRLhntvTyP6B/Q7xHPBc2YKODOSfH0rH8g== + +scale-ts@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/scale-ts/-/scale-ts-1.6.0.tgz#e9641093c5a9e50f964ddb1607139034e3e932e9" + integrity sha512-Ja5VCjNZR8TGKhUumy9clVVxcDpM+YFjAnkMuwQy68Hixio3VRRvWdE3g8T/yC+HXA0ZDQl2TGyUmtmbcVl40Q== + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tslib@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@^2.1.0, tslib@^2.6.2, tslib@^2.6.3, tslib@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + +typescript@^4.1.2: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +vite@^2.5.0: + version "2.9.18" + resolved "https://registry.yarnpkg.com/vite/-/vite-2.9.18.tgz#74e2a83b29da81e602dac4c293312cc575f091c7" + integrity sha512-sAOqI5wNM9QvSEE70W3UGMdT8cyEn0+PmJMTFvTB8wB0YbYUWw3gUbY62AOyrXosGieF2htmeLATvNxpv/zNyQ== + dependencies: + esbuild "^0.14.27" + postcss "^8.4.13" + resolve "^1.22.0" + rollup ">=2.59.0 <2.78.0" + optionalDependencies: + fsevents "~2.3.2" + +ws@8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== diff --git a/substrate/frame/revive/rpc/examples/transfer.rs b/substrate/frame/revive/rpc/examples/transfer.rs index 634131f4da92..ba5182e5730a 100644 --- a/substrate/frame/revive/rpc/examples/transfer.rs +++ b/substrate/frame/revive/rpc/examples/transfer.rs @@ -1,6 +1,5 @@ -use hex_literal::hex; use jsonrpsee::http_client::HttpClientBuilder; -use pallet_revive::evm::{BlockTag, Bytes, ReceiptInfo, H160}; +use pallet_revive::evm::{BlockTag, Bytes, ReceiptInfo}; use pallet_revive_eth_rpc::{ example::{wait_for_receipt, Account}, EthRpcClient, @@ -8,19 +7,26 @@ use pallet_revive_eth_rpc::{ #[tokio::main] async fn main() -> anyhow::Result<()> { - let account = Account::default(); - println!("Account address: {:?}", account.address()); - + let alith = Account::default(); let client = HttpClientBuilder::default().build("http://localhost:9090".to_string())?; - let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?; - println!("Account balance: {:?}", balance); + let baltathar = Account::from(subxt_signer::eth::dev::baltathar()); + let value = 1_000_000_000_000_000_000u128.into(); // 1 ETH + + let print_balance = || async { + let balance = client.get_balance(alith.address(), BlockTag::Latest.into()).await?; + println!("Alith {:?} balance: {balance:?}", alith.address()); + let balance = client.get_balance(baltathar.address(), BlockTag::Latest.into()).await?; + println!("Baltathar {:?} balance: {balance:?}", baltathar.address()); + anyhow::Result::<()>::Ok(()) + }; - let to = Some(H160(hex!("c543bb3eF11d96aCA20b3c906cF2C8Daaff925e4"))); - let value = 10_000_000_000_000_000_000u128.into(); // 10 ETH + print_balance().await?; println!("\n\n=== Transferring ===\n\n"); - let hash = account.send_transaction(&client, value, Bytes::default(), to).await?; + let hash = alith + .send_transaction(&client, value, Bytes::default(), Some(baltathar.address())) + .await?; println!("Transaction hash: {hash:?}"); let ReceiptInfo { block_number, gas_used, .. } = wait_for_receipt(&client, hash).await?; @@ -28,8 +34,6 @@ async fn main() -> anyhow::Result<()> { println!("- Block number: {block_number}"); println!("- Gas used: {gas_used}"); - let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?; - println!("Account balance: {:?}", balance); - + print_balance().await?; Ok(()) } diff --git a/substrate/frame/revive/rpc/src/example.rs b/substrate/frame/revive/rpc/src/example.rs index e6787cef24f6..c7e8e72f35e7 100644 --- a/substrate/frame/revive/rpc/src/example.rs +++ b/substrate/frame/revive/rpc/src/example.rs @@ -18,6 +18,12 @@ impl Default for Account { } } +impl From for Account { + fn from(keypair: subxt_signer::eth::Keypair) -> Self { + Self(keypair) + } +} + /// Wait for a transaction receipt. pub async fn wait_for_receipt(client: &HttpClient, hash: H256) -> anyhow::Result { for _ in 0..6 { From 444970b3cc73b45cbcb192de1df469918371bc9c Mon Sep 17 00:00:00 2001 From: pgherveou Date: Wed, 9 Oct 2024 10:13:34 +0200 Subject: [PATCH 09/37] update yarn.lock --- substrate/frame/revive/rpc/demo/yarn.lock | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/substrate/frame/revive/rpc/demo/yarn.lock b/substrate/frame/revive/rpc/demo/yarn.lock index 744071a85412..6a3de3e17417 100644 --- a/substrate/frame/revive/rpc/demo/yarn.lock +++ b/substrate/frame/revive/rpc/demo/yarn.lock @@ -477,16 +477,6 @@ rxjs@^7.8.1: dependencies: tslib "^2.1.0" -scale-codec@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/scale-codec/-/scale-codec-0.13.0.tgz#7c9842412e0e4fdab5f9f10b475e3fbd40fdb23f" - integrity sha512-HxLaGxglkZP7SwjCLZPMsWGKN8Q/h5bjIH9YLFRcsG3Fmh+qsCOZYRLhntvTyP6B/Q7xHPBc2YKODOSfH0rH8g== - -scale-ts@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/scale-ts/-/scale-ts-1.6.0.tgz#e9641093c5a9e50f964ddb1607139034e3e932e9" - integrity sha512-Ja5VCjNZR8TGKhUumy9clVVxcDpM+YFjAnkMuwQy68Hixio3VRRvWdE3g8T/yC+HXA0ZDQl2TGyUmtmbcVl40Q== - source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" From f10cf13b4368c9ca8c74cb1a70ddb76787cb7563 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Wed, 9 Oct 2024 10:16:47 +0200 Subject: [PATCH 10/37] nit --- substrate/frame/revive/rpc/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/revive/rpc/src/main.rs b/substrate/frame/revive/rpc/src/main.rs index f03d3321fb74..500e1efe7373 100644 --- a/substrate/frame/revive/rpc/src/main.rs +++ b/substrate/frame/revive/rpc/src/main.rs @@ -86,9 +86,9 @@ mod dev { log::info!(target: LOG_TARGET, "method: {method} params: {params}"); let resp = service.call(req).await; if resp.is_success() { - log::info!(target: LOG_TARGET, "✅ method: {method}"); + log::info!(target: LOG_TARGET, "✅ rpc: {method}"); } else { - log::info!(target: LOG_TARGET, "❌ method: {method} {}", resp.as_result()); + log::info!(target: LOG_TARGET, "❌ rpc: {method} {}", resp.as_result()); } resp } From f0e21af67c661c23aa8148741f0341414fc972c6 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Wed, 9 Oct 2024 12:46:37 +0200 Subject: [PATCH 11/37] server fixes --- substrate/frame/revive/rpc/demo/README.md | 59 +++++++++++++++++++ substrate/frame/revive/rpc/demo/package.json | 2 - .../frame/revive/rpc/demo/src/index.html | 1 + substrate/frame/revive/rpc/demo/src/main.ts | 13 +++- substrate/frame/revive/rpc/examples/deploy.rs | 2 + substrate/frame/revive/rpc/src/client.rs | 3 +- 6 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 substrate/frame/revive/rpc/demo/README.md diff --git a/substrate/frame/revive/rpc/demo/README.md b/substrate/frame/revive/rpc/demo/README.md new file mode 100644 index 000000000000..6b9cd12b8420 --- /dev/null +++ b/substrate/frame/revive/rpc/demo/README.md @@ -0,0 +1,59 @@ +## Start the node + +Start the kitchensink node + +```bash +RUST_LOG="error,evm=debug,sc_rpc_server=info,runtime::revive=debug" cargo run --bin substrate-node -- --dev +``` + +## Start the RPC server + +This command starts the Ethereum JSON-RPC server, by default it runs on `localhost:9090` + +```bash +RUST_LOG="info,eth-rpc=debug" cargo run -p pallet-revive-eth-rpc --features dev +``` + +## Send a transaction using provided examples + +You can run one of the examples from the `examples` directory to send a transaction to the node. + +```bash +RUST_LOG="info,eth-rpc=debug" cargo run -p pallet-revive-eth-rpc --features example --example deploy +``` + +## Interact with the node using MetaMask & Ether.js + +Start the Ether.js demo server, and open the demo Ether.js web page at `http://localhost:3000` + +```bash +cd substrate/frame/revive/rpc/demo && yarn && yarn dev +``` + +### Configure MetaMask + +You can use the following instructions to setup [MetaMask](https://metamask.io) with the local chain. + +> Note: When you interact with MetaMask and restart the chain, you need to clear the activity tab (Settings > Advanced > Clear activity tab data) +> See [here](https://support.metamask.io/managing-my-wallet/resetting-deleting-and-restoring/how-to-clear-your-account-activity-reset-account) for more info on how to reset the account activity. + +#### Add a new network + +To interact with the local chain, you need to add a new network in [MetaMask](https://metamask.io). +See [here](https://support.metamask.io/networks-and-sidechains/managing-networks/how-to-add-a-custom-network-rpc/#adding-a-network-manually) for more info on how to add a custom network. + +Make sure the node and the rpc server are started, and use the following settings to configure the network (MetaMask > Networks > Add a network manually): + +- Network name: KitchenSink +- RPC URL: +- Chain ID: 420420420 +- Currency Symbol: `DEV` + +#### Import Dev account + +You will need to import the following account that is endowed with some balance at genesis to interact with the chain. +See [here](https://support.metamask.io/managing-my-wallet/accounts-and-addresses/how-to-import-an-account/) for more info on how to import an account. + +- Account: `0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac` +- Private Key: `5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133` + diff --git a/substrate/frame/revive/rpc/demo/package.json b/substrate/frame/revive/rpc/demo/package.json index a2e7e432013e..8c737a2eca22 100644 --- a/substrate/frame/revive/rpc/demo/package.json +++ b/substrate/frame/revive/rpc/demo/package.json @@ -11,8 +11,6 @@ "author": "", "license": "ISC", "dependencies": { - "@polkadot/types": "^12.2.1", - "@polkadot/util": "^13.0.2", "ethers": "^6.13.1" }, "devDependencies": { diff --git a/substrate/frame/revive/rpc/demo/src/index.html b/substrate/frame/revive/rpc/demo/src/index.html index c479742690d6..8d8bb4d9f432 100644 --- a/substrate/frame/revive/rpc/demo/src/index.html +++ b/substrate/frame/revive/rpc/demo/src/index.html @@ -2,6 +2,7 @@ + Deploy Contract with MetaMask