diff --git a/Cargo.lock b/Cargo.lock index ce6eed5d4..acaca2f93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -740,6 +740,8 @@ dependencies = [ "log", "node-primitives", "pallet-avn", + "pallet-eth-bridge", + "pallet-eth-bridge-runtime-api", "pallet-im-online", "pallet-transaction-payment-rpc", "parity-scale-codec 3.6.4", @@ -826,6 +828,7 @@ dependencies = [ "pallet-balances", "pallet-conviction-voting", "pallet-eth-bridge", + "pallet-eth-bridge-runtime-api", "pallet-ethereum-events", "pallet-im-online", "pallet-nft-manager", @@ -975,17 +978,24 @@ dependencies = [ "jsonrpc-core", "jsonrpsee", "log", + "node-primitives", + "pallet-eth-bridge", + "pallet-eth-bridge-runtime-api", "parity-scale-codec 3.6.4", "sc-client-api", "sc-client-db", "sc-keystore", "sc-service", + "sc-transaction-pool", + "sc-transaction-pool-api", "secp256k1 0.21.3", "secp256k1 0.24.3", "serde", "serde_json", "sp-api", "sp-avn-common", + "sp-block-builder", + "sp-blockchain", "sp-core", "sp-keystore", "sp-runtime", @@ -7175,6 +7185,7 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "scale-info", + "sp-api", "sp-application-crypto", "sp-avn-common", "sp-core", @@ -7184,6 +7195,20 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-eth-bridge-runtime-api" +version = "5.2.2" +dependencies = [ + "frame-support", + "pallet-avn", + "pallet-eth-bridge", + "parity-scale-codec 3.6.4", + "sp-api", + "sp-application-crypto", + "sp-avn-common", + "sp-core", +] + [[package]] name = "pallet-ethereum-events" version = "5.3.1" diff --git a/Cargo.toml b/Cargo.toml index 0e53ed819..e5057490a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ members = [ "node/avn-service", "node/avn-lower-rpc", "pallets/*", + "pallets/*/runtime-api", "primitives/*", "runtime/*", ] diff --git a/Dockerfile.22_04 b/Dockerfile.22_04 index 0b11ec6be..5176a0e34 100644 --- a/Dockerfile.22_04 +++ b/Dockerfile.22_04 @@ -24,6 +24,7 @@ RUN apt-get update && \ ca-certificates \ curl \ jq && \ + update-ca-certificates && \ # apt cleanup apt-get autoremove -y && \ apt-get clean && \ diff --git a/pallets/eth-bridge/Cargo.toml b/pallets/eth-bridge/Cargo.toml index 48c7f6b1c..da3830ba9 100644 --- a/pallets/eth-bridge/Cargo.toml +++ b/pallets/eth-bridge/Cargo.toml @@ -28,6 +28,7 @@ frame-system = { default-features = false, git = "https://github.com/paritytech/ pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v1.0.0" } pallet-session = {default-features = false, features = ["historical"], git = "https://github.com/paritytech/substrate", branch = "polkadot-v1.0.0" } pallet-avn = { default-features = false, path = "../avn" } +sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v1.0.0" } # Optional imports for benchmarking frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v1.0.0", optional = true } @@ -42,6 +43,7 @@ std = [ "frame-benchmarking?/std", "scale-info/std", "codec/std", + "sp-api/std", "sp-std/std", "sp-core/std", "sp-io/std", diff --git a/pallets/eth-bridge/runtime-api/Cargo.toml b/pallets/eth-bridge/runtime-api/Cargo.toml new file mode 100644 index 000000000..a8bb7db2c --- /dev/null +++ b/pallets/eth-bridge/runtime-api/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "pallet-eth-bridge-runtime-api" +description = "Runtime API for module" +license = "GPL-3.0" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } + + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1", features = ["derive"], default-features = false } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v1.0.0" } +pallet-eth-bridge = { default-features = false, path = "../../eth-bridge" } +pallet-avn = { path = "../../avn", default-features = false } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v1.0.0" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v1.0.0" } +sp-avn-common = { default-features = false, path = "../../../primitives/avn-common" } +sp-application-crypto = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v1.0.0" } + + + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-support/std", + "pallet-eth-bridge/std", + "sp-api/std", +] + + diff --git a/pallets/eth-bridge/runtime-api/src/lib.rs b/pallets/eth-bridge/runtime-api/src/lib.rs new file mode 100644 index 000000000..7c792f184 --- /dev/null +++ b/pallets/eth-bridge/runtime-api/src/lib.rs @@ -0,0 +1,25 @@ +#![cfg_attr(not(feature = "std"), no_std)] +use codec::Codec; +use frame_support::dispatch::Vec; +use sp_avn_common::event_discovery::{EthBlockRange, EthereumEventsPartition}; +use sp_core::{H160, H256}; + +sp_api::decl_runtime_apis! { + + #[api_version(1)] + pub trait EthEventHandlerApi + where + AccountId: Codec, + { + fn query_active_block_range()-> (EthBlockRange, u16); + fn query_has_author_casted_event_vote(account_id: AccountId) -> bool; + fn query_signatures() -> Vec; + fn query_bridge_contract() -> H160; + fn create_proof(account_id:AccountId, events_partition:EthereumEventsPartition)-> Vec; + fn submit_vote( + author: AccountId, + events_partition: EthereumEventsPartition, + signature: sp_core::sr25519::Signature + ) -> Result<(), ()>; + } +} diff --git a/pallets/eth-bridge/src/lib.rs b/pallets/eth-bridge/src/lib.rs index c30e152b1..7a25ec6b1 100644 --- a/pallets/eth-bridge/src/lib.rs +++ b/pallets/eth-bridge/src/lib.rs @@ -75,8 +75,11 @@ use pallet_session::historical::IdentificationTuple; use sp_staking::offence::ReportOffence; use sp_application_crypto::RuntimeAppPublic; -use sp_avn_common::{event_discovery::*, event_types::Validator}; -use sp_core::{ecdsa, ConstU32, H256}; +use sp_avn_common::{ + event_discovery::*, + event_types::{ValidEvents, Validator}, +}; +use sp_core::{ecdsa, ConstU32, H160, H256}; use sp_io::hashing::keccak_256; use sp_runtime::{scale_info::TypeInfo, traits::Dispatchable}; use sp_std::prelude::*; @@ -85,7 +88,7 @@ mod call; mod eth; mod request; mod tx; -mod types; +pub mod types; mod util; use crate::types::*; @@ -315,6 +318,7 @@ pub mod pallet { EventVoteExists, NonActiveEthereumRange, VotingEnded, + ValidatorNotFound } #[pallet::call] @@ -678,7 +682,7 @@ pub mod pallet { Ok(()) } - fn author_has_cast_event_vote(author: &T::AccountId) -> bool { + pub fn author_has_cast_event_vote(author: &T::AccountId) -> bool { for (_partition, votes) in EthereumEvents::::iter() { if votes.contains(&author) { return true @@ -876,3 +880,54 @@ pub mod pallet { } } } + +impl Pallet { + pub fn create_eth_events_proof(account_id:T::AccountId, events_partition:EthereumEventsPartition) -> Vec{ + create_ethereum_events_proof_data::(&account_id, &events_partition) + } + pub fn signatures() -> Vec { + let signatures: Vec = match Self::active_ethereum_range() { + Some(active_range) => { + let _events = + active_range.event_types_filter.into_iter().collect::>(); + + let decoded_hex = + hex::decode("418da8f85cfa851601f87634c6950491b6b8785a6445c8584f5658048d512cae"). + expect("test"); + + let mut array = [0; 32]; + array.copy_from_slice(&decoded_hex); + let decoded_event_sig = H256::from(array); + + vec![decoded_event_sig] + }, + None => { + // TODO use values from pallet constant + // vec![] + let decoded_hex = + hex::decode("418da8f85cfa851601f87634c6950491b6b8785a6445c8584f5658048d512cae"). + expect("test"); + + let mut array = [0; 32]; + array.copy_from_slice(&decoded_hex); + let decoded_event_sig = H256::from(array); + + vec![decoded_event_sig] + }, + }; + signatures + } + pub fn submit_vote( + account_id: T::AccountId, + events_partition: EthereumEventsPartition, + signature: ::Signature + ) -> Result<(), ()>{ + let validator: Author = AVN::::validators().into_iter().filter(|v| v.account_id == account_id).nth(0).unwrap(); + + submit_ethereum_events::(validator, events_partition, signature) + } + + pub fn get_bridge_contract() -> H160 { + AVN::::get_bridge_contract_address() + } +} diff --git a/runtime/avn/Cargo.toml b/runtime/avn/Cargo.toml index 37b8b8a37..6f93e823d 100644 --- a/runtime/avn/Cargo.toml +++ b/runtime/avn/Cargo.toml @@ -95,6 +95,7 @@ pallet-nft-manager = { path = "../../pallets/nft-manager", default-features = fa pallet-avn-proxy = { path = "../../pallets/avn-proxy", default-features = false } pallet-avn-transaction-payment = { path = "../../pallets/avn-transaction-payment", default-features = false } pallet-eth-bridge = { path = "../../pallets/eth-bridge", default-features = false } +pallet-eth-bridge-runtime-api = { path = "../../pallets/eth-bridge/runtime-api", default-features = false } pallet-parachain-staking = { path = "../../pallets/parachain-staking", default-features = false } # Common Runtime diff --git a/runtime/avn/src/lib.rs b/runtime/avn/src/lib.rs index 75e57c026..bc84f4cca 100644 --- a/runtime/avn/src/lib.rs +++ b/runtime/avn/src/lib.rs @@ -68,7 +68,7 @@ use pallet_avn::sr25519::AuthorityId as AvnId; pub use pallet_avn_proxy::{Event as AvnProxyEvent, ProvableProxy}; use pallet_avn_transaction_payment::AvnCurrencyAdapter; -use sp_avn_common::{InnerCallValidator, Proof}; +use sp_avn_common::{event_discovery::{EthBlockRange, EthereumEventsPartition}, InnerCallValidator, Proof}; use pallet_parachain_staking; pub type NegativeImbalance = as Currency< @@ -940,6 +940,39 @@ impl_runtime_apis! { TransactionPayment::length_to_fee(length) } } + + impl pallet_eth_bridge_runtime_api::EthEventHandlerApi for Runtime { + fn query_active_block_range()-> (EthBlockRange, u16){ + if let Some(active_eth_range) = EthBridge::active_ethereum_range(){ + (active_eth_range.range, active_eth_range.partition) + }else { + (EthBlockRange::default(), 0) + } + } + fn query_has_author_casted_event_vote(account_id: AccountId) -> bool{ + pallet_eth_bridge::author_has_cast_event_vote::(&account_id) + } + + fn query_signatures() -> Vec { + EthBridge::signatures() + } + + fn query_bridge_contract() -> H160 { + EthBridge::get_bridge_contract() + } + + fn create_proof(account_id:AccountId, events_partition:EthereumEventsPartition)->Vec{ + EthBridge::create_eth_events_proof(account_id, events_partition) + } + + fn submit_vote(author: AccountId, + events_partition: EthereumEventsPartition, + signature: sp_core::sr25519::Signature, + ) -> Result<(),()>{ + EthBridge::submit_vote(author, events_partition, signature.into()) + } + } + impl cumulus_primitives_core::CollectCollationInfo for Runtime { fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { ParachainSystem::collect_collation_info(header)