Skip to content

Commit 1d5d8aa

Browse files
AndreiErespepoviolasw10pa
authored
Rewrite zombienet-polkadot-functional-0012-spam-statement-distribution-requests (paritytech#7657)
Fixes paritytech#5973 --------- Co-authored-by: Javier Viola <[email protected]> Co-authored-by: Javier Viola <[email protected]> Co-authored-by: Stephane Gurgenidze <[email protected]>
1 parent 8b87a0e commit 1d5d8aa

File tree

6 files changed

+246
-78
lines changed

6 files changed

+246
-78
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Zombienet Polkadot
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
types: [opened, synchronize, reopened, ready_for_review]
9+
merge_group:
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
12+
cancel-in-progress: true
13+
14+
env:
15+
RUN_IN_CONTAINER: 1
16+
FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: 1
17+
LOCAL_DIR: "./polkadot/zombienet_tests"
18+
GHA_CLUSTER_SERVER_ADDR: "https://kubernetes.default:443"
19+
20+
# only run if we have changes in [subtrate, polkadot] directories or this workflow.
21+
jobs:
22+
isdraft:
23+
uses: ./.github/workflows/reusable-isdraft.yml
24+
preflight:
25+
needs: isdraft
26+
uses: ./.github/workflows/zombienet-reusable-preflight.yml
27+
28+
zombienet-polkadot-functional-spam-statement-distribution-requests:
29+
needs: [preflight]
30+
if: ${{ needs.preflight.outputs.changes_substrate || needs.preflight.outputs.changes_polkadot }}
31+
runs-on: ${{ needs.preflight.outputs.ZOMBIENET_RUNNER }} # NOTE: should be zombienet-arc-runner (without quotes)
32+
timeout-minutes: 60
33+
container:
34+
image: ${{ needs.preflight.outputs.ZOMBIENET_IMAGE }}
35+
env:
36+
# sdk tests are looking for POLKADOT_IMAGE
37+
POLKADOT_IMAGE: "${{ needs.preflight.outputs.TEMP_IMAGES_BASE }}/polkadot-debug:${{ needs.preflight.outputs.DOCKER_IMAGES_VERSION }}"
38+
COL_IMAGE: "${{ needs.preflight.outputs.TEMP_IMAGES_BASE }}/colander:${{ needs.preflight.outputs.DOCKER_IMAGES_VERSION }}"
39+
MALUS_IMAGE: "${{ needs.preflight.outputs.TEMP_IMAGES_BASE }}/malus:${{ needs.preflight.outputs.DOCKER_IMAGES_VERSION }}"
40+
RUST_LOG: ${{ needs.preflight.outputs.RUST_LOG }}
41+
ZOMBIE_PROVIDER: ${{ needs.preflight.outputs.ZOMBIE_PROVIDER }}
42+
# don't retry sdk tests
43+
NEXTEST_RETRIES: 0
44+
45+
steps:
46+
- name: k8s_auth
47+
shell: bash
48+
run: |
49+
. /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh
50+
k8s_auth
51+
52+
- name: Checkout
53+
uses: actions/checkout@v4
54+
55+
- uses: actions/[email protected]
56+
with:
57+
name: prepare-polkadot-zombienet-artifacts-${{ needs.preflight.outputs.SOURCE_REF_SLUG }}
58+
github-token: ${{ secrets.GITHUB_TOKEN }}
59+
run-id: ${{ needs.preflight.outputs.BUILD_RUN_ID }}
60+
61+
- name: tar
62+
run: tar -xvf artifacts.tar
63+
64+
- name: script
65+
run: |
66+
echo "POLKADOT_IMAGE: $POLKADOT_IMAGE"
67+
echo "COL_IMAGE: $COL_IMAGE"
68+
echo "MALUS_IMAGE: $MALUS_IMAGE"
69+
ls -ltr ./artifacts
70+
# use spot by default
71+
export X_INFRA_INSTANCE=spot
72+
# we want to use `--no-capture` in zombienet tests.
73+
unset NEXTEST_FAILURE_OUTPUT
74+
unset NEXTEST_SUCCESS_OUTPUT
75+
cargo nextest run --archive-file ./artifacts/polkadot-zombienet-tests.tar.zst --no-capture -- functional::spam_statement_distribution_requests::spam_statement_distribution_requests_test
76+
77+
- name: upload logs
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: zombienet-logs-${{ github.job }}-${{ github.sha }}
81+
path: |
82+
/tmp/zombie*/logs/*

.gitlab/pipeline/zombienet/polkadot.yml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,6 @@ zombienet-polkadot-functional-0010-validator-disabling:
152152
--local-dir="${LOCAL_DIR}/functional"
153153
--test="0010-validator-disabling.zndsl"
154154

155-
.zombienet-polkadot-functional-0012-spam-statement-distribution-requests:
156-
extends:
157-
- .zombienet-polkadot-common
158-
script:
159-
- /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh
160-
--local-dir="${LOCAL_DIR}/functional"
161-
--test="0012-spam-statement-distribution-requests.zndsl"
162-
163155
zombienet-polkadot-functional-0013-systematic-chunk-recovery:
164156
extends:
165157
- .zombienet-polkadot-common

polkadot/zombienet-sdk-tests/tests/functional/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33

44
mod async_backing_6_seconds_rate;
55
mod duplicate_collations;
6+
mod spam_statement_distribution_requests;
67
mod sync_backing;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Copyright (C) Parity Technologies (UK) Ltd.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// Test if parachains progress when group is getting spammed by statement distribution requests.
5+
6+
use anyhow::anyhow;
7+
8+
use cumulus_zombienet_sdk_helpers::assert_para_throughput;
9+
use polkadot_primitives::Id as ParaId;
10+
use serde_json::json;
11+
use subxt::{OnlineClient, PolkadotConfig};
12+
use zombienet_sdk::NetworkConfigBuilder;
13+
14+
#[tokio::test(flavor = "multi_thread")]
15+
async fn spam_statement_distribution_requests_test() -> Result<(), anyhow::Error> {
16+
let _ = env_logger::try_init_from_env(
17+
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
18+
);
19+
20+
let images = zombienet_sdk::environment::get_images_from_env();
21+
22+
let config = NetworkConfigBuilder::new()
23+
.with_relaychain(|r| {
24+
r.with_chain("rococo-local")
25+
.with_default_command("polkadot")
26+
.with_default_image(images.polkadot.as_str())
27+
.with_default_args(vec![
28+
// parachain::statement-distribution=trace to find
29+
// "Peer already being served, dropping request"
30+
("-lparachain=debug,parachain::statement-distribution=trace").into(),
31+
])
32+
.with_default_resources(|r| {
33+
r.with_limit_cpu("2")
34+
.with_limit_memory("4G")
35+
.with_request_cpu("1")
36+
.with_request_memory("2G")
37+
})
38+
.with_genesis_overrides(json!({
39+
"configuration": {
40+
"config": {
41+
"needed_approvals": 2,
42+
"scheduler_params": {
43+
"max_validators_per_core": 5
44+
}
45+
}
46+
}
47+
}))
48+
.with_node(|node| node.with_name("honest-0"))
49+
.with_node(|node| node.with_name("honest-1"))
50+
.with_node(|node| node.with_name("honest-2"))
51+
.with_node(|node| node.with_name("honest-3"))
52+
.with_node(|node| {
53+
node.with_name("malus")
54+
.with_image(
55+
std::env::var("MALUS_IMAGE")
56+
.unwrap_or("docker.io/paritypr/malus".to_string())
57+
.as_str(),
58+
)
59+
.with_command("malus")
60+
.with_subcommand("spam-statement-requests")
61+
.with_args(vec![
62+
"--alice".into(),
63+
"--spam-factor=1000".into(),
64+
"--insecure-validator-i-know-what-i-do".into(),
65+
"-lMALUS=trace,parachain=debug".into(),
66+
])
67+
})
68+
})
69+
.with_parachain(|p| {
70+
p.with_id(2000)
71+
.with_default_command("undying-collator")
72+
.cumulus_based(false)
73+
.with_default_image(
74+
std::env::var("COL_IMAGE")
75+
.unwrap_or("docker.io/paritypr/colander:latest".to_string())
76+
.as_str(),
77+
)
78+
.with_default_args(vec![("-lparachain=debug").into()])
79+
.with_collator(|n| n.with_name("collator-2000"))
80+
})
81+
.with_parachain(|p| {
82+
p.with_id(2001)
83+
.with_default_command("undying-collator")
84+
.cumulus_based(false)
85+
.with_default_image(
86+
std::env::var("COL_IMAGE")
87+
.unwrap_or("docker.io/paritypr/colander:latest".to_string())
88+
.as_str(),
89+
)
90+
.with_default_args(vec![("-lparachain=debug").into()])
91+
.with_collator(|n| n.with_name("collator-2001"))
92+
})
93+
.build()
94+
.map_err(|e| {
95+
let errs = e.into_iter().map(|e| e.to_string()).collect::<Vec<_>>().join(" ");
96+
anyhow!("config errs: {errs}")
97+
})?;
98+
99+
let spawn_fn = zombienet_sdk::environment::get_spawn_fn();
100+
let network = spawn_fn(config).await?;
101+
102+
let malus = network.get_node("malus")?;
103+
let honest = network.get_node("honest-0")?;
104+
let relay_client: OnlineClient<PolkadotConfig> = honest.wait_client().await?;
105+
let _malus_client: OnlineClient<PolkadotConfig> = malus.wait_client().await?;
106+
107+
// Check authority status and peers.
108+
malus.assert("node_roles", 4.0).await?;
109+
honest.assert("node_roles", 4.0).await?;
110+
111+
// Ensure parachains are registered.
112+
assert_para_throughput(
113+
&relay_client,
114+
2,
115+
[(ParaId::from(2000), 2..3), (ParaId::from(2001), 2..3)].into_iter().collect(),
116+
)
117+
.await?;
118+
119+
// Ensure that malus is already attempting to DoS
120+
malus
121+
.wait_log_line_count_with_timeout(
122+
"*Duplicating AttestedCandidateV2 request*",
123+
true,
124+
1,
125+
90u64,
126+
)
127+
.await?;
128+
129+
// Ensure parachains made progress.
130+
assert_para_throughput(
131+
&relay_client,
132+
10,
133+
[(ParaId::from(2000), 9..11), (ParaId::from(2001), 9..11)].into_iter().collect(),
134+
)
135+
.await?;
136+
137+
// Ensure that honest nodes drop extra requests.
138+
honest
139+
.wait_log_line_count_with_timeout(
140+
"*Peer already being served, dropping request*",
141+
true,
142+
1,
143+
60u64,
144+
)
145+
.await?;
146+
147+
// Check lag - approval
148+
honest
149+
.assert(
150+
"polkadot_parachain_approval_checking_finality_lag{chain=\"rococo_local_testnet\"}",
151+
0.0,
152+
)
153+
.await?;
154+
155+
// Check lag - dispute conclusion
156+
honest
157+
.assert("polkadot_parachain_disputes_finality_lag{chain=\"rococo_local_testnet\"}", 0.0)
158+
.await?;
159+
160+
log::info!("Test finished successfully");
161+
162+
Ok(())
163+
}

polkadot/zombienet_tests/functional/0012-spam-statement-distribution-requests.toml

Lines changed: 0 additions & 43 deletions
This file was deleted.

polkadot/zombienet_tests/functional/0012-spam-statement-distribution-requests.zndsl

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)