Skip to content

Commit

Permalink
Squashed commit of slava-async-bridge:
Browse files Browse the repository at this point in the history
commit 657deb4cf4b90f24b9c5bfd62764b197776c262c
Author: Hernando Castano <[email protected]>
Date:   Wed Jan 29 20:14:20 2020 -0500

    Move Slava's bridge code into relays folder

commit 4868c42c7da959dde7252766996b3ed4e408e439
Author: Hernando Castano <[email protected]>
Date:   Wed Jan 29 20:01:06 2020 -0500

    Move files into `modules/ethereum`

commit d1093f3e4238acb1a1a020011452cb928d3f8d7a
Merge: 29dc6f9 bfd30ef
Author: Hernando Castano <[email protected]>
Date:   Wed Jan 29 19:59:27 2020 -0500

    Merge branch 'master' of slava-async-bridge

commit 29dc6f97b1b7d1db99086d35a5336f43d2f0f8af
Author: Hernando Castano <[email protected]>
Date:   Wed Jan 29 19:51:31 2020 -0500

    Squashed commit of the following:

    commit 265365920836bb1d286c9b48b1902a2de278fdd9
    Author: Hernando Castano <[email protected]>
    Date:   Wed Jan 29 19:51:15 2020 -0500

        Move hc-jp-bridge repo to different folder

    commit 8271991e95320baba70bd1cb9c4234d0ffd5b638
    Merge: 57d0811 304cbc5
    Author: Hernando Castano <[email protected]>
    Date:   Wed Jan 29 19:36:41 2020 -0500

        Merge branch 'hc-jp-bridge-module' of hc-jp-bridge-module

    commit 304cbc5f02d003ffa5404c1c01e461e5b8539888
    Author: Hernando Castano <[email protected]>
    Date:   Wed Jan 29 00:38:27 2020 -0500

        Update bridge pallet to work with the (almost) lastest master (paritytech#4672)

        * Update decl_error usage

        * WIP: Update error handling to use DispatchResult

        * Get module compiling with new error handling

        * Make tests compile again

        Main change was updating the usage of InMemoryBackend

        * Move `sp-state-machine` into dev-dependencies

        * Bump dependencies to v2.0.0

        * Remove some stray comments

        * Appy code review suggestion

    commit 510cd6d96372688517496efa61773ea2839f8474
    Author: Hernando Castano <[email protected]>
    Date:   Tue Dec 17 12:52:51 2019 -0500

        Move Bridge Pallet into FRAME (paritytech#4373)

        * Move `bridge` crate into `frame` folder

        * Make `bridge` pallet compile after `the-big-reorg`

    commit ab54e838ef75e6a3f68fd0944bf22598c10c552f
    Author: Hernando Castano <[email protected]>
    Date:   Mon Nov 11 21:56:40 2019 +0100

        Use new StorageProof type from paritytech#3834

    commit 8fc8911fd1b4acc2274c6863fb3dba91b30c90af
    Author: Hernando Castano <[email protected]>
    Date:   Tue Nov 5 00:50:34 2019 +0100

        Verify Ancestry between Headers (paritytech#3963)

        * Create module for checking ancestry proofs

        * Use Vec of Headers instead of a HashMap

        * Move the ancestry verification into the lib.rs file

        * Change the proof format to exclude `child` and `ancestor` headers

        * Add a testing function for building header chains

        * Rename AncestorNotFound error to InvalidAncestryProof

        * Use ancestor hash instead of header when verifying ancestry

        * Clean up some stuff missed in the merge

    commit dbe85738b68358b790cf927b34a804b965a88f96
    or: Hernando Castano <[email protected]>
    Date:   Fri Nov 1 15:41:58 2019 +0100

        Check given Grandpa validator set against set found in storage (paritytech#3915)

        * Make StorageProofChecker happy

        * Update some tests

        * Check given validator set against set found in storage

        * Use Finality Grandpa's Authority Id and Weight

        * Add better error handling

        * Use error type from decl_error! macro

    commit 31b09216603d3e9c21144ce8c0b6bf59307a4f97
    or: Hernando Castano <[email protected]>
    Date:   Wed Oct 23 14:55:37 2019 +0200

        Make tests work after the changes introduced in paritytech#3793 (paritytech#3874)

        * Make tests work after the changes introduced in paritytech#3793

        * Remove unneccessary import

    commit bce6d804aa86504599ff912387295c58f846cbf3
    Author: Jim Posen <[email protected]>
    Date:   Thu Oct 10 12:18:58 2019 +0200

        Logic for checking Substrate proofs from within runtime module. (paritytech#3783)

    commit a7013e94b6c772c1d45a7cacbb445f73f6554fca
    Author: Hernando Castano <[email protected]>
    Date:   Fri Oct 4 15:21:00 2019 +0300

        Allow tracking of multiple bridges

    commit 3cf648242d631e32bd553a67df54bf5a48912839
    Author: Hernando Castano <[email protected]>
    Date:   Tue Oct 1 14:55:04 2019 +0200

        Add BridgeId => Bridge mapping

    commit 001c74c45072213e01857d0a2454379b447c5a76
    Author: Hernando Castano <[email protected]>
    Date:   Tue Oct 1 11:10:19 2019 +0200

        Get the mock runtime for tests set up

    commit 38443a1e8b424ed2f148eb95121d009f730e3b5a
    Author: Hernando Castano <[email protected]>
    Date:   Fri Sep 27 14:52:53 2019 +0200

        Clean up some warnings

    commit bdc3b01401e89c7111f8bf71f84c50750d25089f
    Author: Hernando Castano <[email protected]>
    Date:   Thu Sep 26 16:41:01 2019 +0200

        Add more skeleton code

    commit 26995efbf4bac2842eb2822322f7ad3c3e88feb8
    Author: Hernando Castano <[email protected]>
    Date:   Wed Sep 25 15:16:57 2019 +0200

        Create `bridge` module skeleton

commit bfd30ef8363b1483ef1107ae1eb958a4e944c93b
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Tue Dec 10 12:10:53 2019 +0300

    actually use signer from CLI to sign Substrate transactions

commit 504028eac60d9d14ba95b506cd355b0d2f405ce0
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Tue Dec 10 12:02:22 2019 +0300

    go offline for a bit on connection error

commit 446d0c8d20187dfd1beb173958ea28f2ad97887d
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Tue Dec 10 11:25:50 2019 +0300

    enable info logs by default

commit d039c60ec72bc91adfdad85442bc99a93b7f8e8d
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Tue Dec 10 11:12:51 2019 +0300

    support basic CLI arguments

commit 65c6d48e23576f36e8541878b920a03730226392
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 15:37:48 2019 +0300

    fix restart

commit 96e94c1c4b22d732078f8c401b872c5f8246c3fe
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 14:57:53 2019 +0300

    license

commit 68f4191e6cdd211ac8975e0b79f8a6f46a3ca953
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 14:56:05 2019 +0300

    restart sync when Substrate reorgs && we are unlucky

commit 29887c446167d580d73cc03a0b71c31890cafb51
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 13:49:31 2019 +0300

    only read genesis hash once

commit 832492b8393fe2063adf9c58c2b9e060dc3e4efb
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 13:23:26 2019 +0300

    changed TODO

commit 9dbc130e5fa036ae63d973819daf30f4ed6ffb5b
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 13:16:56 2019 +0300

    removed obsolete exit future

commit d03408cd8284eb0c61e7e96429b4f6199353e030
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 13:16:17 2019 +0300

    removed obsolete TODOs + moved a couple of TODOs to runtime module

commit ed8bec44b79f9a2ce829e59f10181368b2f42139
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 12:37:05 2019 +0300

    explained TODO fix

commit aa9c4c66ec2904eeb6072d654718b0ac0b7d8803
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 12:28:09 2019 +0300

    fix tx outcome serialization

commit 126f8f5484dac8c4af588ae86dc8855919d6c822
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Mon Dec 9 12:05:05 2019 +0300

    prune old ethereum headers when Substrate best header is too far in the future

commit c7bd301e631a44fe3263e188d0956081aa84f31e
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Fri Dec 6 12:51:50 2019 +0300

    fix trace

commit 549bb7acdb30cfdafe6c8600f0410212539ea63d
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Fri Dec 6 12:51:26 2019 +0300

    tx hashes are already a part of Block response

commit 7864017909f87ea36955d605a924c3c88bc88df3
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Thu Dec 5 12:29:37 2019 +0300

    submit bunch of headers at once + some fixes

commit 96485f85d38c144f0771f02ba692216a60356665
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Wed Dec 4 17:22:13 2019 +0300

    print status messages

commit ae0ec4c087136db653339537daab7f96a8c21b65
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Wed Dec 4 17:06:00 2019 +0300

    continue actual Substrate client implementation

commit 8146293740d70b88904568ff8e5acdfbadf06fd3
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Wed Dec 4 13:49:30 2019 +0300

    fix IncompleteHeader condition

commit 767c6201157dabcccf7f62e643681ca298224fb1
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Wed Dec 4 10:55:06 2019 +0300

    actual Substrate client implementation

commit 221fd4ccd2b1eea12c9dacf800d80e15ec115c1b
Author: Svyatoslav Nikolsky <[email protected]>
Date:   Wed Nov 20 17:28:13 2019 +0300

    initial commit
  • Loading branch information
HCastano authored and bkchr committed Apr 10, 2024
1 parent d530bf2 commit 479c5bd
Show file tree
Hide file tree
Showing 13 changed files with 9,349 additions and 0 deletions.
6,274 changes: 6,274 additions & 0 deletions bridges/relays/ethereum/Cargo.lock

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions bridges/relays/ethereum/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "async-bridge"
version = "0.1.0"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"

[dependencies]
ansi_term = "0.9"
async-std = "1.0.1"
async-stream = "0.2.0"
clap = { version = "2.33.0", features = ["yaml"] }
codec = { package = "parity-scale-codec", version = "1.0.0" }
env_logger = "0.7.0"
frame-system = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
futures = "0.3.1"
jsonrpsee-core = { git = "https://github.com/paritytech/jsonrpsee.git" }
jsonrpsee-http = { git = "https://github.com/paritytech/jsonrpsee.git" }
linked-hash-map = "0.5.2"
log = "0.4.8"
node-primitives = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
node-runtime = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
pallet-transaction-payment = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
parking_lot = "0.9.0"
rustc-hex = "2.0.1"
serde = { version = "1.0.40", features = ["derive"] }
serde_json = "1.0.40"
sp-bridge-eth-poa = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
sp-core = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
sp-keyring = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
sp-runtime = { git = "https://github.com/svyatonik/substrate.git", branch = "bridge_runtime" }
time = "0.1"
web3 = { git = "https://github.com/svyatonik/rust-web3.git", branch = "fix_receipt" }
675 changes: 675 additions & 0 deletions bridges/relays/ethereum/LICENSE

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions bridges/relays/ethereum/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# PoA <> Substrate Bridge

**DISCLAIMER:** *we recommend not using the bridge in "production" (to bridge significant amounts) just yet.
it's missing a code audit and should still be considered alpha. we can't rule out that there are bugs that might result in loss of the bridged amounts.
we'll update this disclaimer once that changes*

These docs are very incomplete yet. Describe high-level goals here in the (near) future.
33 changes: 33 additions & 0 deletions bridges/relays/ethereum/src/cli.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: ethsub-bridge
version: "0.1.0"
author: Parity Technologies <[email protected]>
about: Parity Ethereum (PoA) <-> Substrate bridge
args:
- eth-host:
long: eth-host
value_name: ETH_HOST
help: Connect to Ethereum node at given host.
takes_value: true
- eth-port:
long: eth-port
value_name: ETH_PORT
help: Connect to Ethereum node at given port.
takes_value: true
- sub-host:
long: sub-host
value_name: SUB_HOST
help: Connect to Substrate node at given host.
takes_value: true
- sub-port:
long: sub-port
value_name: SUB_PORT
help: Connect to Substrate node at given port.
takes_value: true
- sub-signer:
long: sub-signer
value_name: SUB_SIGNER
help: The SURI of secret key to use when transactions are submitted to the Substrate node.
- sub-signer-password:
long: sub-signer-password
value_name: SUB_SIGNER_PASSWORD
help: The password for the SURI of secret key to use when transactions are submitted to the Substrate node.
170 changes: 170 additions & 0 deletions bridges/relays/ethereum/src/ethereum_client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Parity-Bridge.

// Parity-Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity-Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity-Bridge. If not, see <http://www.gnu.org/licenses/>.

use jsonrpsee_core::{client::ClientError, common::Params};
use jsonrpsee_http::{HttpClient, RequestError, http_client};
use serde::de::DeserializeOwned;
use serde_json::{from_value, to_value};
use crate::ethereum_sync_loop::MaybeConnectionError;
use crate::ethereum_types::{H256, Header, HeaderId, Receipt, U64};

/// Proof of hash serialization success.
const HASH_SERIALIZATION_PROOF: &'static str = "hash serialization never fails; qed";
/// Proof of integer serialization success.
const INT_SERIALIZATION_PROOF: &'static str = "integer serialization never fails; qed";
/// Proof of bool serialization success.
const BOOL_SERIALIZATION_PROOF: &'static str = "bool serialization never fails; qed";

/// Ethereum client type.
pub type Client = HttpClient;

/// All possible errors that can occur during interacting with Ethereum node.
#[derive(Debug)]
pub enum Error {
/// Request start failed.
StartRequestFailed(RequestError),
/// Request not found (should never occur?).
RequestNotFound,
/// Failed to receive response.
ResponseRetrievalFailed(ClientError<RequestError>),
/// Failed to parse response.
ResponseParseFailed(serde_json::Error),
/// We have received header with missing number and hash fields.
IncompleteHeader,
/// We have received receipt with missing gas_used field.
IncompleteReceipt,
}

impl MaybeConnectionError for Error {
fn is_connection_error(&self) -> bool {
match *self {
Error::StartRequestFailed(_) | Error::ResponseRetrievalFailed(_) => true,
_ => false,
}
}
}

/// Returns client that is able to call RPCs on Ethereum node.
pub fn client(uri: &str) -> Client {
http_client(uri)
}

/// Retrieve best known block number from Ethereum node.
pub async fn best_block_number(client: Client) -> (Client, Result<u64, Error>) {
let (client, result) = call_rpc::<U64>(
client,
"eth_blockNumber",
Params::None,
).await;
(client, result.map(|x| x.as_u64()))
}

/// Retrieve block header by its number from Ethereum node.
pub async fn header_by_number(client: Client, number: u64) -> (Client, Result<Header, Error>) {
let (client, header) = call_rpc(
client,
"eth_getBlockByNumber",
Params::Array(vec![
to_value(U64::from(number)).expect(INT_SERIALIZATION_PROOF),
to_value(false).expect(BOOL_SERIALIZATION_PROOF),
]),
).await;
(client, header.and_then(|header: Header| match header.number.is_some() && header.hash.is_some() {
true => Ok(header),
false => Err(Error::IncompleteHeader),
}))
}

/// Retrieve block header by its hash from Ethereum node.
pub async fn header_by_hash(client: Client, hash: H256) -> (Client, Result<Header, Error>) {
let (client, header) = call_rpc(
client,
"eth_getBlockByHash",
Params::Array(vec![
to_value(hash).expect(HASH_SERIALIZATION_PROOF),
to_value(false).expect(BOOL_SERIALIZATION_PROOF),
]),
).await;
(client, header.and_then(|header: Header| match header.number.is_none() && header.hash.is_none() {
true => Ok(header),
false => Err(Error::IncompleteHeader),
}))
}

/// Retrieve transactions receipts for given block.
pub async fn transactions_receipts(
mut client: Client,
id: HeaderId,
transacactions: Vec<H256>,
) -> (Client, Result<(HeaderId, Vec<Receipt>), Error>) {
let mut transactions_receipts = Vec::with_capacity(transacactions.len());
for transacaction in transacactions {
let (next_client, transaction_receipt) = transaction_receipt(client, transacaction).await;
let transaction_receipt = match transaction_receipt {
Ok(transaction_receipt) => transaction_receipt,
Err(error) => return (next_client, Err(error)),
};
transactions_receipts.push(transaction_receipt);
client = next_client;
}
(client, Ok((id, transactions_receipts)))
}

/// Retrieve transaction receipt by transaction hash.
async fn transaction_receipt(client: Client, hash: H256) -> (Client, Result<Receipt, Error>) {
let (client, receipt) = call_rpc::<Receipt>(
client,
"eth_getTransactionReceipt",
Params::Array(vec![
to_value(hash).expect(HASH_SERIALIZATION_PROOF),
]),
).await;
(client, receipt.and_then(|receipt| {
match receipt.gas_used.is_some() {
true => Ok(receipt),
false => Err(Error::IncompleteReceipt),
}
}))
}

/// Calls RPC on Ethereum node.
async fn call_rpc<T: DeserializeOwned>(
mut client: Client,
method: &'static str,
params: Params,
) -> (Client, Result<T, Error>) {
async fn do_call_rpc<T: DeserializeOwned>(
client: &mut Client,
method: &'static str,
params: Params,
) -> Result<T, Error> {
let request_id = client
.start_request(method, params)
.await
.map_err(Error::StartRequestFailed)?;
// WARN: if there'll be need for executing >1 request at a time, we should avoid
// calling request_by_id
let response = client
.request_by_id(request_id)
.ok_or(Error::RequestNotFound)?
.await
.map_err(Error::ResponseRetrievalFailed)?;
from_value(response).map_err(Error::ResponseParseFailed)
}

let result = do_call_rpc(&mut client, method, params).await;
(client, result)
}
Loading

0 comments on commit 479c5bd

Please sign in to comment.