Skip to content

Commit 10c94e5

Browse files
authored
Merge branch 'main' into A0-1796-broadcast-ticker
2 parents 3cc1a9e + a3ab96e commit 10c94e5

File tree

21 files changed

+695
-132
lines changed

21 files changed

+695
-132
lines changed

.github/actions/run-e2e-test/action.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ inputs:
2626
follow-up-finalization-check:
2727
description: 'Whether to run a follow-up finalization check.'
2828
required: false
29+
deploy-adder:
30+
description: 'Whether to deploy the adder sample contract to the node.'
31+
required: false
32+
default: 'false'
2933

3034
runs:
3135
using: 'composite'
@@ -84,6 +88,14 @@ runs:
8488
)
8589
fi
8690
91+
DEPLOY_ADDER="${{ inputs.deploy-adder }}"
92+
93+
if [[ "${DEPLOY_ADDER}" = "true" ]]; then
94+
pushd contracts/adder
95+
export ADDER=$(./deploy.sh)
96+
popd
97+
fi
98+
8799
./.github/scripts/run_e2e_test.sh "${ARGS[@]}"
88100
89101
- name: Run finalization e2e test

.github/scripts/run_e2e_test.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ if [[ -n "${ONLY_LEGACY:-}" ]]; then
111111
ARGS+=(-e ONLY_LEGACY)
112112
fi
113113

114-
docker run -v $(pwd)/docker/data:/data "${ARGS[@]}" aleph-e2e-client:latest
114+
if [[ -n "${ADDER:-}" ]]; then
115+
ARGS+=(-e "ADDER=${ADDER}")
116+
ARGS+=(-e "ADDER_METADATA=/contracts/adder/target/ink/metadata.json")
117+
fi
118+
119+
docker run -v "$(pwd)/contracts:/contracts" -v "$(pwd)/docker/data:/data" "${ARGS[@]}" aleph-e2e-client:latest
115120

116121
exit $?

.github/workflows/check-excluded-packages.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,6 @@ jobs:
3232
with:
3333
version: '3.6.1'
3434

35-
- name: Install clippy and fmt
36-
run: rustup component add clippy rustfmt
37-
38-
- name: Install WASM target
39-
run: rustup target add wasm32-unknown-unknown
40-
4135
- name: Read excluded packages from Cargo.toml
4236
id: read_excluded
4337
uses: SebRollen/[email protected]
@@ -75,6 +69,8 @@ jobs:
7569
do
7670
echo "Checking package $p..."
7771
pushd "$p"
72+
rustup component add clippy rustfmt
73+
rustup target add wasm32-unknown-unknown
7874
cargo fmt --all --check
7975
cargo clippy --all-features -- --no-deps -D warnings
8076
popd

.github/workflows/e2e-tests-main-devnet.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,31 @@ jobs:
552552
UPGRADE_FINALIZATION_WAIT_SESSIONS: 2
553553
timeout-minutes: 10
554554

555+
run-e2e-adder-contract-test:
556+
needs: [build-test-docker, build-test-client]
557+
name: Run e2e adder contract test
558+
runs-on: ubuntu-20.04
559+
steps:
560+
- name: Checkout source code
561+
uses: actions/checkout@v2
562+
563+
- name: Install cargo-contract
564+
uses: baptiste0928/cargo-install@v1
565+
with:
566+
crate: cargo-contract
567+
version: "2.0.0-beta.1"
568+
569+
- name: Install rust-src
570+
working-directory: ./contracts
571+
run: rustup component add rust-src
572+
573+
- name: Run e2e test
574+
uses: ./.github/actions/run-e2e-test
575+
with:
576+
deploy-adder: true
577+
test-case: adder
578+
timeout-minutes: 10
579+
555580
# The tests below were written under the assumption that nonfinalized blocks are being produced, they need a rewrite before being reenabled.
556581
# TODO(A0-1644): Reenable these tests.
557582
# run-e2e-failing-version-upgrade:
@@ -659,6 +684,7 @@ jobs:
659684
run-e2e-ban-threshold,
660685
run-e2e-version-upgrade,
661686
run-e2e-permissionless-ban,
687+
run-e2e-adder-contract-test,
662688
# run-e2e-failing-version-upgrade,
663689
# run-e2e-version-upgrade-catchup,
664690
]

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ exclude = [
1818
"fork-off",
1919
"benches/payout-stakers",
2020
"bin/cliain",
21+
"contracts/adder"
2122
]
2223

2324
[profile.release]

aleph-client/src/connections.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,14 @@ impl SignedConnection {
142142
if let Some(details) = tx.validation_details() {
143143
info!(target:"aleph-client", "Sending extrinsic {}.{} with params: {:?}", details.pallet_name, details.call_name, params);
144144
}
145+
145146
let progress = self
146147
.connection
147148
.client
148149
.tx()
149150
.sign_and_submit_then_watch(&tx, &self.signer, params)
150-
.await?;
151+
.await
152+
.map_err(|e| anyhow!("Failed to submit transaction: {:?}", e))?;
151153

152154
// In case of Submitted hash does not mean anything
153155
let hash = match status {
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
use std::{fmt::Debug, ops::Deref, str::FromStr};
2+
3+
use anyhow::{anyhow, bail, Context, Result};
4+
use contract_transcode::Value;
5+
6+
use crate::AccountId;
7+
8+
/// Temporary wrapper for converting from [Value] to primitive types.
9+
///
10+
/// ```
11+
/// # #![feature(assert_matches)]
12+
/// # #![feature(type_ascription)]
13+
/// # use std::assert_matches::assert_matches;
14+
/// # use anyhow::{anyhow, Result};
15+
/// # use aleph_client::{AccountId, contract::ConvertibleValue};
16+
/// use contract_transcode::Value;
17+
///
18+
/// assert_matches!(ConvertibleValue(Value::UInt(42)).try_into(), Ok(42u128));
19+
/// assert_matches!(ConvertibleValue(Value::UInt(42)).try_into(), Ok(42u32));
20+
/// assert_matches!(ConvertibleValue(Value::UInt(u128::MAX)).try_into(): Result<u32>, Err(_));
21+
/// assert_matches!(ConvertibleValue(Value::Bool(true)).try_into(), Ok(true));
22+
/// assert_matches!(
23+
/// ConvertibleValue(Value::Literal("5H8cjBBzCJrAvDn9LHZpzzJi2UKvEGC9VeVYzWX5TrwRyVCA".to_string())).
24+
/// try_into(): Result<AccountId>,
25+
/// Ok(_)
26+
/// );
27+
/// assert_matches!(
28+
/// ConvertibleValue(Value::String("not a number".to_string())).try_into(): Result<u128>,
29+
/// Err(_)
30+
/// );
31+
/// ```
32+
#[derive(Debug, Clone)]
33+
pub struct ConvertibleValue(pub Value);
34+
35+
impl Deref for ConvertibleValue {
36+
type Target = Value;
37+
38+
fn deref(&self) -> &Value {
39+
&self.0
40+
}
41+
}
42+
43+
impl TryFrom<ConvertibleValue> for bool {
44+
type Error = anyhow::Error;
45+
46+
fn try_from(value: ConvertibleValue) -> Result<bool, Self::Error> {
47+
match value.0 {
48+
Value::Bool(value) => Ok(value),
49+
_ => bail!("Expected {:?} to be a boolean", value.0),
50+
}
51+
}
52+
}
53+
54+
impl TryFrom<ConvertibleValue> for u128 {
55+
type Error = anyhow::Error;
56+
57+
fn try_from(value: ConvertibleValue) -> Result<u128, Self::Error> {
58+
match value.0 {
59+
Value::UInt(value) => Ok(value),
60+
_ => bail!("Expected {:?} to be an integer", value.0),
61+
}
62+
}
63+
}
64+
65+
impl TryFrom<ConvertibleValue> for u32 {
66+
type Error = anyhow::Error;
67+
68+
fn try_from(value: ConvertibleValue) -> Result<u32, Self::Error> {
69+
match value.0 {
70+
Value::UInt(value) => Ok(value.try_into()?),
71+
_ => bail!("Expected {:?} to be an integer", value.0),
72+
}
73+
}
74+
}
75+
76+
impl TryFrom<ConvertibleValue> for AccountId {
77+
type Error = anyhow::Error;
78+
79+
fn try_from(value: ConvertibleValue) -> Result<AccountId, Self::Error> {
80+
match value.0 {
81+
Value::Literal(value) => {
82+
AccountId::from_str(&value).map_err(|_| anyhow!("Invalid account id"))
83+
}
84+
_ => bail!("Expected {:?} to be a string", value),
85+
}
86+
}
87+
}
88+
89+
impl<T> TryFrom<ConvertibleValue> for Result<T>
90+
where
91+
ConvertibleValue: TryInto<T, Error = anyhow::Error>,
92+
{
93+
type Error = anyhow::Error;
94+
95+
fn try_from(value: ConvertibleValue) -> Result<Result<T>, Self::Error> {
96+
if let Value::Tuple(tuple) = &value.0 {
97+
match tuple.ident() {
98+
Some(x) if x == "Ok" => {
99+
if tuple.values().count() == 1 {
100+
let item =
101+
ConvertibleValue(tuple.values().next().unwrap().clone()).try_into()?;
102+
return Ok(Ok(item));
103+
} else {
104+
bail!("Unexpected number of elements in Ok variant: {:?}", &value);
105+
}
106+
}
107+
Some(x) if x == "Err" => {
108+
if tuple.values().count() == 1 {
109+
return Ok(Err(anyhow!(value.to_string())));
110+
} else {
111+
bail!("Unexpected number of elements in Err variant: {:?}", &value);
112+
}
113+
}
114+
_ => (),
115+
}
116+
}
117+
118+
bail!("Expected {:?} to be an Ok(_) or Err(_) tuple.", value);
119+
}
120+
}
121+
122+
impl TryFrom<ConvertibleValue> for String {
123+
type Error = anyhow::Error;
124+
125+
fn try_from(value: ConvertibleValue) -> std::result::Result<String, Self::Error> {
126+
let seq = match value.0 {
127+
Value::Seq(seq) => seq,
128+
_ => bail!("Failed parsing `ConvertibleValue` to `String`. Expected `Seq(Value::UInt)` but instead got: {:?}", value),
129+
};
130+
131+
let mut bytes: Vec<u8> = Vec::with_capacity(seq.len());
132+
for el in seq.elems() {
133+
if let Value::UInt(byte) = *el {
134+
if byte > u8::MAX as u128 {
135+
bail!("Expected number <= u8::MAX but instead got: {:?}", byte)
136+
}
137+
bytes.push(byte as u8);
138+
} else {
139+
bail!("Failed parsing `ConvertibleValue` to `String`. Expected `Value::UInt` but instead got: {:?}", el);
140+
}
141+
}
142+
String::from_utf8(bytes).context("Failed parsing bytes to UTF-8 String.")
143+
}
144+
}
145+
146+
auto trait NotEq {}
147+
// We're basically telling the compiler that there is no instance of NotEq for `(X,X)` tuple.
148+
// Or put differently - that you can't implement `NotEq` for `(X,X)`.
149+
impl<X> !NotEq for (X, X) {}
150+
151+
impl<T> TryFrom<ConvertibleValue> for Option<T>
152+
where
153+
T: TryFrom<ConvertibleValue, Error = anyhow::Error> + Debug,
154+
// We will derive this impl only when `T != ConvertibleValue`.
155+
// Otherwise we will get a conflict with generic impl in the rust `core` crate.
156+
(ConvertibleValue, T): NotEq,
157+
{
158+
type Error = anyhow::Error;
159+
160+
fn try_from(value: ConvertibleValue) -> std::result::Result<Option<T>, Self::Error> {
161+
let tuple = match &value.0 {
162+
Value::Tuple(tuple) => tuple,
163+
_ => bail!("Expected {:?} to be a Some(_) or None Tuple.", &value),
164+
};
165+
166+
match tuple.ident() {
167+
Some(x) if x == "Some" => {
168+
if tuple.values().count() == 1 {
169+
let item =
170+
ConvertibleValue(tuple.values().next().unwrap().clone()).try_into()?;
171+
Ok(Some(item))
172+
} else {
173+
bail!(
174+
"Unexpected number of elements in Some(_) variant: {:?}. Expected one.",
175+
&value
176+
);
177+
}
178+
}
179+
Some(x) if x == "None" => {
180+
if tuple.values().count() == 0 {
181+
Ok(None)
182+
} else {
183+
bail!(
184+
"Unexpected number of elements in None variant: {:?}. Expected zero.",
185+
&value
186+
);
187+
}
188+
}
189+
_ => bail!(
190+
"Expected `.ident()` to be `Some` or `None`, got: {:?}",
191+
&tuple
192+
),
193+
}
194+
}
195+
}

0 commit comments

Comments
 (0)