Skip to content

Commit

Permalink
Merge branch 'master' into giles-delete-logging-code
Browse files Browse the repository at this point in the history
  • Loading branch information
bkchr authored Apr 12, 2024
2 parents 7225120 + c963dc2 commit 30c1dec
Show file tree
Hide file tree
Showing 75 changed files with 3,192 additions and 735 deletions.
158 changes: 158 additions & 0 deletions .github/workflows/sync-templates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: Synchronize templates


# This job is used to keep the repository templates up-to-date.
# The code of the templates exist inside the monorepo, and upon releases we synchronize the repositories:
# - https://github.com/paritytech/polkadot-sdk-minimal-template
# - https://github.com/paritytech/polkadot-sdk-parachain-template
# - https://github.com/paritytech/polkadot-sdk-solochain-template
#
# The job moves the template code out of the monorepo,
# replaces any references to the monorepo workspace using psvm and toml-cli,
# checks that it builds successfully,
# and commits and pushes the result to each respective repository.
# If the build fails, a PR is created instead for manual inspection.


on:
# A manual dispatch for now - automatic on releases later.
workflow_dispatch:
inputs:
crate_release_version:
description: 'A release version to use, e.g. 1.9.0'
required: true


jobs:
sync-templates:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
template: ["minimal", "solochain", "parachain"]
env:
template-path: "polkadot-sdk-${{ matrix.template }}-template"
steps:

# 1. Prerequisites.

- name: Configure git identity
run: |
git config --global user.name "Template Bot"
git config --global user.email "163342540+paritytech-polkadotsdk-templatebot[bot]@users.noreply.github.com"
- uses: actions/checkout@v3
with:
path: polkadot-sdk
ref: "release-crates-io-v${{ github.event.inputs.crate_release_version }}"
- name: Generate a token for the template repository
id: app_token
uses: actions/[email protected]
with:
owner: "paritytech"
repositories: "polkadot-sdk-${{ matrix.template }}-template"
app-id: ${{ secrets.TEMPLATE_APP_ID }}
private-key: ${{ secrets.TEMPLATE_APP_KEY }}
- uses: actions/checkout@v3
with:
repository: "paritytech/polkadot-sdk-${{ matrix.template }}-template"
path: "${{ env.template-path }}"
token: ${{ steps.app_token.outputs.token }}
- name: Install toml-cli
run: cargo install --git https://github.com/gnprice/toml-cli --rev ea69e9d2ca4f0f858110dc7a5ae28bcb918c07fb # v0.2.3
- name: Install Polkadot SDK Version Manager
run: cargo install --git https://github.com/paritytech/psvm --rev c41261ffb52ab0c115adbbdb17e2cb7900d2bdfd psvm # master
- name: Rust compilation prerequisites
run: |
sudo apt update
sudo apt install -y \
protobuf-compiler
rustup target add wasm32-unknown-unknown
rustup component add rustfmt clippy rust-src
# 2. Yanking the template out of the monorepo workspace.

- name: Use psvm to replace git references with released creates.
run: find . -type f -name 'Cargo.toml' -exec psvm -o -v ${{ github.event.inputs.crate_release_version }} -p {} \;
working-directory: polkadot-sdk/templates/${{ matrix.template }}/
- name: Create a new workspace Cargo.toml
run: |
cat << EOF > Cargo.toml
[workspace.package]
license = "MIT-0"
authors = ["Parity Technologies <[email protected]>"]
homepage = "https://substrate.io"
[workspace]
members = [
"node",
"pallets/template",
"runtime",
]
resolver = "2"
EOF
shell: bash
working-directory: polkadot-sdk/templates/${{ matrix.template }}/
- name: Update workspace configuration
run: |
set -euo pipefail
# toml-cli has no overwrite functionality yet, so we use temporary files.
# We cannot pipe the output straight to the same file while the CLI still reads and processes it.
toml set templates/${{ matrix.template }}/Cargo.toml 'workspace.package.repository' "https://github.com/paritytech/polkadot-sdk-${{ matrix.template }}-template.git" > Cargo.temp
mv Cargo.temp ./templates/${{ matrix.template }}/Cargo.toml
toml set templates/${{ matrix.template }}/Cargo.toml 'workspace.package.edition' "$(toml get --raw Cargo.toml 'workspace.package.edition')" > Cargo.temp
mv Cargo.temp ./templates/${{ matrix.template }}/Cargo.toml
toml get Cargo.toml 'workspace.lints' --output-toml >> ./templates/${{ matrix.template }}/Cargo.toml
toml get Cargo.toml 'workspace.dependencies' --output-toml >> ./templates/${{ matrix.template }}/Cargo.toml
working-directory: polkadot-sdk
- name: Print the result Cargo.tomls for debugging
if: runner.debug == '1'
run: find . -type f -name 'Cargo.toml' -exec cat {} \;
working-directory: polkadot-sdk/templates/${{ matrix.template }}/

- name: Clean the destination repository
run: rm -rf ./*
working-directory: "${{ env.template-path }}"
- name: Copy over the new changes
run: |
cp -r polkadot-sdk/templates/${{ matrix.template }}/* "${{ env.template-path }}/"
# 3. Verify the build. Push the changes or create a PR.

# We've run into out-of-disk error when compiling in the next step, so we free up some space this way.
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # 1.3.1
with:
android: true # This alone is a 12 GB save.
# We disable the rest because it caused some problems. (they're enabled by default)
# The Android removal is enough.
dotnet: false
haskell: false
large-packages: false
swap-storage: false

- name: Check if it compiles
id: check-compilation
run: cargo check && cargo test
working-directory: "${{ env.template-path }}"
timeout-minutes: 90
- name: Create PR on failure
if: failure() && steps.check-compilation.outcome == 'failure'
uses: peter-evans/create-pull-request@5b4a9f6a9e2af26e5f02351490b90d01eb8ec1e5 # v5
with:
path: "${{ env.template-path }}"
token: ${{ steps.app_token.outputs.token }}
add-paths: |
./*
title: "[Don't merge] Update the ${{ matrix.template }} template"
body: "The template has NOT been successfully built and needs to be inspected."
branch: "update-template/${{ github.event_name }}"
- name: Push changes
run: |
git add -A .
git commit --allow-empty -m "Update template triggered by ${{ github.event_name }}"
git push
working-directory: "${{ env.template-path }}"
2 changes: 2 additions & 0 deletions .gitlab/pipeline/zombienet/polkadot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ zombienet-polkadot-functional-0011-async-backing-6-seconds-rate:
zombienet-polkadot-elastic-scaling-0001-basic-3cores-6s-blocks:
extends:
- .zombienet-polkadot-common
variables:
FORCED_INFRA_INSTANCE: "spot-iops"
script:
- /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh
--local-dir="${LOCAL_DIR}/elastic_scaling"
Expand Down
205 changes: 205 additions & 0 deletions bridges/bin/runtime-common/src/extensions/check_obsolete_extension.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.

// Parity Bridges Common 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 Bridges Common 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 Bridges Common. If not, see <http://www.gnu.org/licenses/>.

//! Transaction extension that rejects bridge-related transactions, that include
//! obsolete (duplicated) data or do not pass some additional pallet-specific
//! checks.
use crate::messages_call_ext::MessagesCallSubType;
use pallet_bridge_grandpa::CallSubType as GrandpaCallSubType;
use pallet_bridge_parachains::CallSubType as ParachainsCallSubtype;
use sp_runtime::transaction_validity::TransactionValidity;

/// A duplication of the `FilterCall` trait.
///
/// We need this trait in order to be able to implement it for the messages pallet,
/// since the implementation is done outside of the pallet crate.
pub trait BridgeRuntimeFilterCall<Call> {
/// Checks if a runtime call is valid.
fn validate(call: &Call) -> TransactionValidity;
}

impl<T, I: 'static> BridgeRuntimeFilterCall<T::RuntimeCall> for pallet_bridge_grandpa::Pallet<T, I>
where
T: pallet_bridge_grandpa::Config<I>,
T::RuntimeCall: GrandpaCallSubType<T, I>,
{
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
GrandpaCallSubType::<T, I>::check_obsolete_submit_finality_proof(call)
}
}

impl<T, I: 'static> BridgeRuntimeFilterCall<T::RuntimeCall>
for pallet_bridge_parachains::Pallet<T, I>
where
T: pallet_bridge_parachains::Config<I>,
T::RuntimeCall: ParachainsCallSubtype<T, I>,
{
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
ParachainsCallSubtype::<T, I>::check_obsolete_submit_parachain_heads(call)
}
}

impl<T: pallet_bridge_messages::Config<I>, I: 'static> BridgeRuntimeFilterCall<T::RuntimeCall>
for pallet_bridge_messages::Pallet<T, I>
where
T::RuntimeCall: MessagesCallSubType<T, I>,
{
/// Validate messages in order to avoid "mining" messages delivery and delivery confirmation
/// transactions, that are delivering outdated messages/confirmations. Without this validation,
/// even honest relayers may lose their funds if there are multiple relays running and
/// submitting the same messages/confirmations.
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
call.check_obsolete_call()
}
}

/// Declares a runtime-specific `BridgeRejectObsoleteHeadersAndMessages` signed extension.
///
/// ## Example
///
/// ```nocompile
/// generate_bridge_reject_obsolete_headers_and_messages!{
/// Call, AccountId
/// BridgeRococoGrandpa, BridgeRococoMessages,
/// BridgeRococoParachains
/// }
/// ```
///
/// The goal of this extension is to avoid "mining" transactions that provide outdated bridged
/// headers and messages. Without that extension, even honest relayers may lose their funds if
/// there are multiple relays running and submitting the same information.
#[macro_export]
macro_rules! generate_bridge_reject_obsolete_headers_and_messages {
($call:ty, $account_id:ty, $($filter_call:ty),*) => {
#[derive(Clone, codec::Decode, Default, codec::Encode, Eq, PartialEq, sp_runtime::RuntimeDebug, scale_info::TypeInfo)]
pub struct BridgeRejectObsoleteHeadersAndMessages;
impl sp_runtime::traits::SignedExtension for BridgeRejectObsoleteHeadersAndMessages {
const IDENTIFIER: &'static str = "BridgeRejectObsoleteHeadersAndMessages";
type AccountId = $account_id;
type Call = $call;
type AdditionalSigned = ();
type Pre = ();

fn additional_signed(&self) -> sp_std::result::Result<
(),
sp_runtime::transaction_validity::TransactionValidityError,
> {
Ok(())
}

fn validate(
&self,
_who: &Self::AccountId,
call: &Self::Call,
_info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
_len: usize,
) -> sp_runtime::transaction_validity::TransactionValidity {
let valid = sp_runtime::transaction_validity::ValidTransaction::default();
$(
let valid = valid
.combine_with(<$filter_call as $crate::extensions::check_obsolete_extension::BridgeRuntimeFilterCall<$call>>::validate(call)?);
)*
Ok(valid)
}

fn pre_dispatch(
self,
who: &Self::AccountId,
call: &Self::Call,
info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, sp_runtime::transaction_validity::TransactionValidityError> {
self.validate(who, call, info, len).map(drop)
}
}
};
}

#[cfg(test)]
mod tests {
use super::*;
use frame_support::{assert_err, assert_ok};
use sp_runtime::{
traits::SignedExtension,
transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
};

pub struct MockCall {
data: u32,
}

impl sp_runtime::traits::Dispatchable for MockCall {
type RuntimeOrigin = ();
type Config = ();
type Info = ();
type PostInfo = ();

fn dispatch(
self,
_origin: Self::RuntimeOrigin,
) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
unimplemented!()
}
}

struct FirstFilterCall;
impl BridgeRuntimeFilterCall<MockCall> for FirstFilterCall {
fn validate(call: &MockCall) -> TransactionValidity {
if call.data <= 1 {
return InvalidTransaction::Custom(1).into()
}

Ok(ValidTransaction { priority: 1, ..Default::default() })
}
}

struct SecondFilterCall;
impl BridgeRuntimeFilterCall<MockCall> for SecondFilterCall {
fn validate(call: &MockCall) -> TransactionValidity {
if call.data <= 2 {
return InvalidTransaction::Custom(2).into()
}

Ok(ValidTransaction { priority: 2, ..Default::default() })
}
}

#[test]
fn test() {
generate_bridge_reject_obsolete_headers_and_messages!(
MockCall,
(),
FirstFilterCall,
SecondFilterCall
);

assert_err!(
BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 1 }, &(), 0),
InvalidTransaction::Custom(1)
);

assert_err!(
BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 2 }, &(), 0),
InvalidTransaction::Custom(2)
);

assert_ok!(
BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 3 }, &(), 0),
ValidTransaction { priority: 3, ..Default::default() }
)
}
}
21 changes: 21 additions & 0 deletions bridges/bin/runtime-common/src/extensions/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.

// Parity Bridges Common 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 Bridges Common 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 Bridges Common. If not, see <http://www.gnu.org/licenses/>.

//! Bridge-specific transaction extensions.
pub mod check_obsolete_extension;
pub mod priority_calculator;
pub mod refund_relayer_extension;
Loading

0 comments on commit 30c1dec

Please sign in to comment.