Process finality proofs in solidity PoA -> Substrate contract (#69)

* solidity contract

* continue

* upd

* cargo update

* fixes

* ehtereum_headers -> headers

* extracted some common stuff

* ethereum_sync.rs -> sync.rs

* make sync generic

* continue extracting

* continue

* add eth-contract argument

* continue

* some fixes

* contract v2

* continue

* more fixes

* more fixes

* deal with duplicated params

* removed multiple call_rpc variants

* bail_on_error!()

* fn submit_ethereum_transaction

* more fixes

* cargo fmt --all

* fix

* bail_on_arg_error!()

* fix

* fix

* remove async_extra stuff

* start work on finality builtin

remove async_extra stuff

continue

continue

local testnet (Alice + Bob) for node

* added TODO

* substrate-bridge.json -> substrate-bridge-abi.json

* get rid of substrate transactions hashes

* get rid of ethereum transactions hashes

* extracted contract bytecode to separate file

* cargo fmt --all

* avoid duplicate import in contracts

* removed Default::default()

* swapped configurations for sub2eth && eth2sub

* fix compilation

* do not double gas limit when submitting Substrate headers

* fix finality storage

* at least 1 validator required

* shift_session_manager_works

* cargo fmt --all

* solidity contract removed

* consts

* extracted solc compilation details to separate file

* removed (obsolete in future Vec<u8> justification)

* fixed cli option description

* fix typos

* fix grumble

* extracted constants

* log decoded header

* new substrate version + actually verify justification

* intermediate cargo fmt --all

* comments

* disable completion data resubmission

* increased timeouts + _MS -> Duration

* forget completion data after submission

* builtin tests

* headers tests

* cargo fmt --all

* update contract

* Update relays/ethereum/src/ethereum_sync_loop.rs

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Update relays/ethereum/src/ethereum_sync_loop.rs

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* added docs

* OwnedFutureOutput

* more docs fixes

* cargo fmt --all

* encode headers

* consts + docs

* aliases again

* cargo fmt --all

* Update relays/ethereum/src/ethereum_sync_loop.rs

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Update relays/ethereum/src/ethereum_sync_loop.rs

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Use Duration::from_secs() instead of from_millis()

* grumbles

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* incomplete_headers_are_still_incomplete_after_advance

* add hex-encoded headers to substrate_header_without_signal_parsed

* cargo fmt --all

* Update relays/ethereum/src/sync_loop.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Update relays/ethereum/src/headers.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* added comments on Extra and Completion

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
This commit is contained in:
Svyatoslav Nikolsky
2020-05-13 00:09:26 +03:00
committed by Bastian Köcher
parent 9496303aff
commit c9e81e48b5
14 changed files with 1190 additions and 214 deletions
@@ -14,19 +14,21 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Ethereum PoA -> Substrate synchronization.
use crate::ethereum_client::{self, EthereumConnectionParams};
use crate::ethereum_types::{EthereumHeaderId, EthereumHeadersSyncPipeline, Header, QueuedEthereumHeader, Receipt};
use crate::substrate_client::{self, SubstrateConnectionParams, SubstrateSigningParams};
use crate::sync::{HeadersSyncParams, TargetTransactionMode};
use crate::sync_loop::{SourceClient, TargetClient};
use futures::future::FutureExt;
use std::{future::Future, pin::Pin};
use crate::sync_loop::{OwnedSourceFutureOutput, OwnedTargetFutureOutput, SourceClient, TargetClient};
use futures::future::{ready, FutureExt, Ready};
use std::{collections::HashSet, future::Future, pin::Pin, time::Duration};
use web3::types::H256;
/// Interval (in ms) at which we check new Ethereum headers when we are synced/almost synced.
const ETHEREUM_TICK_INTERVAL_MS: u64 = 10_000;
/// Interval (in ms) at which we check new Substrate blocks.
const SUBSTRATE_TICK_INTERVAL_MS: u64 = 5_000;
/// Interval at which we check new Ethereum headers when we are synced/almost synced.
const ETHEREUM_TICK_INTERVAL: Duration = Duration::from_secs(10);
/// Interval at which we check new Substrate blocks.
const SUBSTRATE_TICK_INTERVAL: Duration = Duration::from_secs(5);
/// Max number of headers in single submit transaction.
const MAX_HEADERS_IN_SINGLE_SUBMIT: usize = 32;
/// Max total size of headers in single submit transaction. This only affects signed
@@ -76,13 +78,15 @@ struct EthereumHeadersSource {
client: ethereum_client::Client,
}
type EthereumFutureOutput<T> = OwnedSourceFutureOutput<EthereumHeadersSource, EthereumHeadersSyncPipeline, T>;
impl SourceClient<EthereumHeadersSyncPipeline> for EthereumHeadersSource {
type Error = ethereum_client::Error;
type BestBlockNumberFuture = Pin<Box<dyn Future<Output = (Self, Result<u64, Self::Error>)>>>;
type HeaderByHashFuture = Pin<Box<dyn Future<Output = (Self, Result<Header, Self::Error>)>>>;
type HeaderByNumberFuture = Pin<Box<dyn Future<Output = (Self, Result<Header, Self::Error>)>>>;
type HeaderExtraFuture =
Pin<Box<dyn Future<Output = (Self, Result<(EthereumHeaderId, Vec<Receipt>), Self::Error>)>>>;
type BestBlockNumberFuture = Pin<Box<dyn Future<Output = EthereumFutureOutput<u64>>>>;
type HeaderByHashFuture = Pin<Box<dyn Future<Output = EthereumFutureOutput<Header>>>>;
type HeaderByNumberFuture = Pin<Box<dyn Future<Output = EthereumFutureOutput<Header>>>>;
type HeaderExtraFuture = Pin<Box<dyn Future<Output = EthereumFutureOutput<(EthereumHeaderId, Vec<Receipt>)>>>>;
type HeaderCompletionFuture = Ready<EthereumFutureOutput<(EthereumHeaderId, Option<()>)>>;
fn best_block_number(self) -> Self::BestBlockNumberFuture {
ethereum_client::best_block_number(self.client)
@@ -107,6 +111,10 @@ impl SourceClient<EthereumHeadersSyncPipeline> for EthereumHeadersSource {
.map(|(client, result)| (EthereumHeadersSource { client }, result))
.boxed()
}
fn header_completion(self, id: EthereumHeaderId) -> Self::HeaderCompletionFuture {
ready((self, Ok((id, None))))
}
}
/// Substrate client as Ethereum headers target.
@@ -119,12 +127,16 @@ struct SubstrateHeadersTarget {
sign_params: SubstrateSigningParams,
}
type SubstrateFutureOutput<T> = OwnedTargetFutureOutput<SubstrateHeadersTarget, EthereumHeadersSyncPipeline, T>;
impl TargetClient<EthereumHeadersSyncPipeline> for SubstrateHeadersTarget {
type Error = substrate_client::Error;
type BestHeaderIdFuture = Pin<Box<dyn Future<Output = (Self, Result<EthereumHeaderId, Self::Error>)>>>;
type IsKnownHeaderFuture = Pin<Box<dyn Future<Output = (Self, Result<(EthereumHeaderId, bool), Self::Error>)>>>;
type RequiresExtraFuture = Pin<Box<dyn Future<Output = (Self, Result<(EthereumHeaderId, bool), Self::Error>)>>>;
type SubmitHeadersFuture = Pin<Box<dyn Future<Output = (Self, Result<Vec<EthereumHeaderId>, Self::Error>)>>>;
type BestHeaderIdFuture = Pin<Box<dyn Future<Output = SubstrateFutureOutput<EthereumHeaderId>>>>;
type IsKnownHeaderFuture = Pin<Box<dyn Future<Output = SubstrateFutureOutput<(EthereumHeaderId, bool)>>>>;
type RequiresExtraFuture = Pin<Box<dyn Future<Output = SubstrateFutureOutput<(EthereumHeaderId, bool)>>>>;
type SubmitHeadersFuture = Pin<Box<dyn Future<Output = SubstrateFutureOutput<Vec<EthereumHeaderId>>>>>;
type IncompleteHeadersFuture = Ready<SubstrateFutureOutput<HashSet<EthereumHeaderId>>>;
type CompleteHeadersFuture = Ready<SubstrateFutureOutput<EthereumHeaderId>>;
fn best_header_id(self) -> Self::BestHeaderIdFuture {
let (sign_transactions, sign_params) = (self.sign_transactions, self.sign_params);
@@ -192,6 +204,14 @@ impl TargetClient<EthereumHeadersSyncPipeline> for SubstrateHeadersTarget {
})
.boxed()
}
fn incomplete_headers_ids(self) -> Self::IncompleteHeadersFuture {
ready((self, Ok(HashSet::new())))
}
fn complete_header(self, id: EthereumHeaderId, _completion: ()) -> Self::CompleteHeadersFuture {
ready((self, Ok(id)))
}
}
/// Run Ethereum headers synchronization.
@@ -206,13 +226,13 @@ pub fn run(params: EthereumSyncParams) {
crate::sync_loop::run(
EthereumHeadersSource { client: eth_client },
ETHEREUM_TICK_INTERVAL_MS,
ETHEREUM_TICK_INTERVAL,
SubstrateHeadersTarget {
client: sub_client,
sign_transactions: sign_sub_transactions,
sign_params: params.sub_sign,
},
SUBSTRATE_TICK_INTERVAL_MS,
SUBSTRATE_TICK_INTERVAL,
params.sync_params,
);
}