Skip to content

Commit 4b58dcc

Browse files
authored
Network-degradation experiment (#522)
* Designed network-degradation experiment * Designed analysis notebook * Completed degradation experiment * Updated logbook
1 parent 52748af commit 4b58dcc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+112160
-0
lines changed

Logbook.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Leios logbook
22

3+
## 2025-08-26
4+
5+
### Network degradation experiment
6+
7+
The simulation experiment [analysis/sims/degraded/](analysis/sims/degraded/) studied Leios's behavior when network topology is thinned. The number of connections to/from each node was randomly thinned by up to 87% of its original mainnet-like topology. Beyond that level (i.e., more than 88% of connections lost), the network topology splits into disconnected regions where some nodes can no longer communicate with each other. That degradation resulted in the diameter of the network increasing from 5 hops to 8 hops and the number of connections per node dropping form 23.5 to 6.0. Both honest cases and cases where adversaries delay the release or transactions and EBs were studied. The experiment was inconclusive, in that the protocol operated properly when 87% of connections where lost.
8+
39
## 2025-08-25
410

511
### Bandwidth experiment

analysis/sims/degraded/analysis.ipynb

Lines changed: 3842 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env nix-shell
2+
#!nix-shell -i bash -p gnused gzip pigz "rWrapper.override { packages = with rPackages; [ data_table R_utils bit64 ggplot2 magrittr stringr ]; }"
3+
4+
set -e
5+
6+
mkdir -p results/$d
7+
for f in lifecycle resources receipts cpus sizes
8+
do
9+
DIR=$(find experiments -type f -name $f.csv.gz \( -not -empty \) -printf %h\\n -quit)
10+
HL=$(sed -n -e '1p' "$DIR/case.csv")
11+
HR=$(zcat "$DIR/$f.csv.gz" | sed -n -e '1p')
12+
if [[ "$f" == "lifecycle" || "$f" == "resources" || "$f" == "sizes" ]]
13+
then
14+
FRACT=1.00
15+
else
16+
FRACT=0.25
17+
fi
18+
(
19+
echo "$HL,$HR"
20+
for g in $(find experiments -type f -name $f.csv.gz \( -not -empty \) -printf %h\\n)
21+
do
22+
if [ ! -e "$g/stderr" ]
23+
then
24+
echo "Skipping $g because it has no stderr." >> /dev/stderr
25+
elif [ -s "$g/stderr" ]
26+
then
27+
echo "Skipping $g because its stderr is not empty." >> /dev/stderr
28+
else
29+
BL=$(sed -n -e '2p' "$g/case.csv")
30+
zcat "$g/$f.csv.gz" | gawk 'FNR > 1 && rand() <= '"$FRACT"' { print "'"$BL"'" "," $0}'
31+
fi
32+
done
33+
) | pigz -p 3 -9c > results/$f.csv.gz
34+
R --vanilla << EOI > /dev/null
35+
require(data.table)
36+
sampleSize <- $FRACT
37+
print(sampleSize)
38+
$f <- fread("results/$f.csv.gz", stringsAsFactors=TRUE)
39+
save($f, sampleSize, file="results/$f.Rdata", compression_level=9)
40+
EOI
41+
done
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
experiments/0.15,0.0,0/run.sh
2+
experiments/0.15,7.0,1/run.sh
3+
experiments/0.30,0.0,0/run.sh
4+
experiments/0.30,7.0,1/run.sh
5+
experiments/0.45,0.0,0/run.sh
6+
experiments/0.45,7.0,1/run.sh
7+
experiments/0.60,0.0,0/run.sh
8+
experiments/0.60,7.0,1/run.sh
9+
experiments/0.75,0.0,0/run.sh
10+
experiments/0.75,7.0,1/run.sh
11+
experiments/0.90,0.0,0/run.sh
12+
experiments/0.90,7.0,1/run.sh
13+
experiments/0.13,0.0,0/run.sh
14+
experiments/0.13,7.0,1/run.sh
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Connectivity,Adversary,EB delay,Tx attack,Tx size,Throughput,Tx start [s],Tx stop [s],Sim stop [s]
2+
0.13,33% adversary,EB attack: none,Tx attack: none,1500 B/Tx,0.150 TxMB/s,60,960,1200
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"timestamp-resolution-ms": 0.1,
3+
"simulate-transactions": true,
4+
"cleanup-policies": [
5+
"cleanup-expired-vote"
6+
],
7+
"leios-variant": "linear-with-tx-references",
8+
"linear-eb-propagation-criteria": "eb-received",
9+
"linear-vote-stage-length-slots": 7,
10+
"linear-diffuse-stage-length-slots": 7,
11+
"praos-fallback-enabled": true,
12+
"leios-stage-active-voting-slots": 1,
13+
"leios-mempool-sampling-strategy": "ordered-by-id",
14+
"relay-strategy": "request-from-first",
15+
"treat-blocks-as-full": false,
16+
"eb-diffusion-strategy": "peer-order",
17+
"eb-referenced-txs-max-size-bytes": 12000000,
18+
"eb-size-bytes-constant": 240,
19+
"eb-size-bytes-per-ib": 32,
20+
"leios-header-diffusion-time-ms": 2000.0,
21+
"tx-start-time": 60,
22+
"tx-stop-time": 960,
23+
"tx-generation-distribution": {
24+
"distribution": "constant",
25+
"value": 10.000
26+
},
27+
"tx-size-bytes-distribution": {
28+
"distribution": "constant",
29+
"value": 1500
30+
},
31+
"tx-conflict-fraction": 0,
32+
"tx-overcollateralization-factor-distribution": {
33+
"distribution": "constant",
34+
"value": 0
35+
},
36+
"tx-validation-cpu-time-ms": 0.6201,
37+
"tx-max-size-bytes": 16384,
38+
"rb-generation-probability": 0.05,
39+
"rb-head-size-bytes": 1024,
40+
"rb-body-max-size-bytes": 90112,
41+
"rb-generation-cpu-time-ms": 71.02,
42+
"rb-head-validation-cpu-time-ms": 0.4438,
43+
"eb-header-validation-cpu-time-ms": 0.4438,
44+
"rb-body-legacy-praos-payload-validation-cpu-time-ms-constant": 0.3539,
45+
"rb-body-legacy-praos-payload-validation-cpu-time-ms-per-byte": 0.00002151,
46+
"eb-body-validation-cpu-time-ms-constant": 0.3539,
47+
"eb-body-validation-cpu-time-ms-per-byte": 0.00002151,
48+
"vote-generation-probability": 600,
49+
"vote-threshold": 450,
50+
"vote-bundle-size-bytes-constant": 0,
51+
"vote-bundle-size-bytes-per-eb": 164,
52+
"vote-generation-cpu-time-ms-constant": 0.28,
53+
"vote-generation-cpu-time-ms-per-tx": 0,
54+
"vote-validation-cpu-time-ms": 2.9,
55+
"vote-diffusion-strategy": "peer-order",
56+
"vote-diffusion-max-bodies-to-request": 1,
57+
"vote-diffusion-max-headers-to-request": 100,
58+
"vote-diffusion-max-window-size": 100,
59+
"cert-size-bytes-constant": 8000,
60+
"cert-size-bytes-per-node": 0,
61+
"cert-generation-cpu-time-ms-constant": 92.5,
62+
"cert-generation-cpu-time-ms-per-node": 0,
63+
"cert-validation-cpu-time-ms-constant": 157.2,
64+
"cert-validation-cpu-time-ms-per-node": 0,
65+
"late-eb-attack": {
66+
"attackers": {
67+
"nodes": []
68+
},
69+
"propagation-delay-ms": 0
70+
},
71+
"late-tx-attack": {
72+
"attackers": {
73+
"nodes": []
74+
},
75+
"attack-probability": 0,
76+
"tx-generation-distribution": {
77+
"distribution": "constant",
78+
"value": 0
79+
}
80+
}
81+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Topology Analysis Report
2+
3+
Analysis of: network.yaml
4+
5+
## Network Statistics
6+
7+
| Metric | Value |
8+
|--------|-------|
9+
| Total nodes | 750 |
10+
| Block producers | 216 |
11+
| Relay nodes | 534 |
12+
| Total connections | 4475 |
13+
| Network diameter | 8 hops |
14+
| Average connections per node | 5.97 |
15+
| Clustering coefficient | 0.285 |
16+
| Average latency | 37.0ms ms |
17+
| Maximum latency | 509.6ms ms |
18+
| Stake-weighted latency | 0.0ms ms |
19+
| Bidirectional connections | 584 |
20+
| Asymmetry ratio | 73.90% |
21+
22+
## Stake Distribution
23+
24+
| Metric | Value |
25+
|--------|-------|
26+
| Total stake | 12697141247 |
27+
| Gini coefficient | 0.743 |
28+
29+
### Top 5 Stake Holders
30+
31+
| Node | Stake | % of Total |
32+
|------|--------|------------|
33+
| node-48 | 78570315 | 0.62% |
34+
| node-486 | 74078634 | 0.58% |
35+
| node-49 | 76601989 | 0.60% |
36+
| node-50 | 75578906 | 0.60% |
37+
| node-531 | 74130184 | 0.58% |
38+
39+
### Geographic Stake Distribution
40+
41+
| Region | Nodes | Total Stake | % of Network |
42+
|---------|--------|-------------|-------------|
43+
44+
## Network Reliability
45+
46+
The following nodes, if removed, would isolate significant stake:
47+
48+
| Node | Isolated Stake | % of Total Stake |
49+
|------|----------------|------------------|
50+
| node-672 | 66036506 | 0.52% |
51+
52+
## Geographic Validation
53+
54+
✅ No geographic violations found
55+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../run.sh
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
INFO praos: sim_cli::events: 90001 transactions(s) were generated in total.
2+
INFO praos: sim_cli::events: 51 naive praos block(s) were published.
3+
INFO praos: sim_cli::events: 1149 slot(s) had no naive praos blocks.
4+
INFO praos: sim_cli::events: 90001 transaction(s) (135.00 MB) finalized in a naive praos block.
5+
INFO praos: sim_cli::events: 0 transaction(s) (0 B) did not reach a naive praos block.
6+
INFO praos: sim_cli::events: Pool 37 published 1 naive praos block(s)
7+
INFO praos: sim_cli::events: Pool 38 published 1 naive praos block(s)
8+
INFO praos: sim_cli::events: Pool 46 published 1 naive praos block(s)
9+
INFO praos: sim_cli::events: Pool 51 published 1 naive praos block(s)
10+
INFO praos: sim_cli::events: Pool 53 published 1 naive praos block(s)
11+
INFO praos: sim_cli::events: Pool 54 published 1 naive praos block(s)
12+
INFO praos: sim_cli::events: Pool 55 published 1 naive praos block(s)
13+
INFO praos: sim_cli::events: Pool 59 published 1 naive praos block(s)
14+
INFO praos: sim_cli::events: Pool 61 published 2 naive praos block(s)
15+
INFO praos: sim_cli::events: Pool 67 published 1 naive praos block(s)
16+
INFO praos: sim_cli::events: Pool 68 published 0 naive praos block(s)
17+
INFO praos: sim_cli::events: Pool 68 failed to publish 1 naive praos block(s) due to slot battles.
18+
INFO praos: sim_cli::events: Pool 75 published 2 naive praos block(s)
19+
INFO praos: sim_cli::events: Pool 86 published 1 naive praos block(s)
20+
INFO praos: sim_cli::events: Pool 88 published 1 naive praos block(s)
21+
INFO praos: sim_cli::events: Pool 89 published 1 naive praos block(s)
22+
INFO praos: sim_cli::events: Pool 90 published 1 naive praos block(s)
23+
INFO praos: sim_cli::events: Pool 91 published 1 naive praos block(s)
24+
INFO praos: sim_cli::events: Pool 93 published 2 naive praos block(s)
25+
INFO praos: sim_cli::events: Pool 100 failed to publish 1 naive praos block(s) due to slot battles.
26+
INFO praos: sim_cli::events: Pool 104 published 1 naive praos block(s)
27+
INFO praos: sim_cli::events: Pool 117 published 1 naive praos block(s)
28+
INFO praos: sim_cli::events: Pool 121 published 1 naive praos block(s)
29+
INFO praos: sim_cli::events: Pool 132 published 1 naive praos block(s)
30+
INFO praos: sim_cli::events: Pool 136 published 1 naive praos block(s)
31+
INFO praos: sim_cli::events: Pool 351 published 1 naive praos block(s)
32+
INFO praos: sim_cli::events: Pool 364 published 1 naive praos block(s)
33+
INFO praos: sim_cli::events: Pool 373 published 2 naive praos block(s)
34+
INFO praos: sim_cli::events: Pool 418 published 1 naive praos block(s)
35+
INFO praos: sim_cli::events: Pool 430 published 1 naive praos block(s)
36+
INFO praos: sim_cli::events: Pool 442 published 1 naive praos block(s)
37+
INFO praos: sim_cli::events: Pool 443 published 1 naive praos block(s)
38+
INFO praos: sim_cli::events: Pool 480 published 1 naive praos block(s)
39+
INFO praos: sim_cli::events: Pool 510 published 1 naive praos block(s)
40+
INFO praos: sim_cli::events: Pool 511 published 1 naive praos block(s)
41+
INFO praos: sim_cli::events: Pool 517 published 1 naive praos block(s)
42+
INFO praos: sim_cli::events: Pool 519 published 1 naive praos block(s)
43+
INFO praos: sim_cli::events: Pool 523 published 1 naive praos block(s)
44+
INFO praos: sim_cli::events: Pool 527 published 1 naive praos block(s)
45+
INFO praos: sim_cli::events: Pool 534 published 1 naive praos block(s)
46+
INFO praos: sim_cli::events: Pool 538 published 1 naive praos block(s)
47+
INFO praos: sim_cli::events: Pool 539 published 1 naive praos block(s)
48+
INFO praos: sim_cli::events: Pool 540 published 1 naive praos block(s)
49+
INFO praos: sim_cli::events: Pool 542 published 1 naive praos block(s)
50+
INFO praos: sim_cli::events: Pool 544 published 3 naive praos block(s)
51+
INFO praos: sim_cli::events: Pool 562 published 1 naive praos block(s)
52+
INFO praos: sim_cli::events: Pool 741 published 1 naive praos block(s)
53+
INFO praos: sim_cli::events: Pool 745 published 1 naive praos block(s)
54+
INFO leios: sim_cli::events: 0 IB(s) were generated, on average 0.000 IB(s) per slot.
55+
INFO leios: sim_cli::events: 0 out of 90001 transaction(s) were included in at least one IB.
56+
INFO leios: sim_cli::events: The average age of the pending transactions is NaNs (stddev NaN).
57+
INFO leios: sim_cli::events: Each transaction was included in an average of NaN IB(s) (stddev NaN).
58+
INFO leios: sim_cli::events: Each IB contained an average of NaN transaction(s) (stddev NaN) and an average of 0 B (stddev 0 B). 0 IB(s) were empty.
59+
INFO leios: sim_cli::events: Each node received an average of 0.000 IB(s) (stddev 0.000).
60+
INFO leios: sim_cli::events: 53 EB(s) were generated; on average there were 0.044 EB(s) per slot.
61+
INFO leios: sim_cli::events: Each EB contained an average of 4032.509 transaction(s) (stddev 2650.790). 7 EB(s) were empty.
62+
INFO leios: sim_cli::events: Each EB contained an average of 0.000 IB(s) (stddev 0.000). 7 EB(s) were empty.
63+
INFO leios: sim_cli::events: Each IB was included in an average of NaN EB(s) (stddev NaN).
64+
INFO leios: sim_cli::events: 0 out of 0 IBs were included in at least one EB.
65+
INFO leios: sim_cli::events: 0 out of 0 IBs expired before they reached an EB.
66+
INFO leios: sim_cli::events: 12 out of 53 EBs expired before an EB from their stage reached an RB.
67+
INFO leios: sim_cli::events: 89941 out of 90001 transaction(s) were included in at least one EB.
68+
INFO leios: sim_cli::events: 26700 total votes were generated.
69+
INFO leios: sim_cli::events: Each stake pool produced an average of 123.611 vote(s) (stddev 24.778).
70+
INFO leios: sim_cli::events: Each EB received an average of 503.774 vote(s) (stddev 211.763).
71+
INFO leios: sim_cli::events: There were 8941 bundle(s) of votes. Each bundle contained 2.986 vote(s) (stddev 1.630).
72+
INFO leios: sim_cli::events: 44 L1 block(s) had a Leios endorsement.
73+
INFO leios: sim_cli::events: 89461 tx(s) (134.19 MB) were referenced by a Leios endorsement.
74+
INFO leios: sim_cli::events: 540 tx(s) (810 kB) were included directly in a Praos block.
75+
INFO leios: sim_cli::events: Spatial efficiency: 134.19 MB/7.20 MB (1862.773%) of Leios bytes were unique transactions.
76+
INFO leios: sim_cli::events: 66480 tx(s) (42.632%) referenced by a Leios endorsement were redundant.
77+
INFO leios: sim_cli::events: Each transaction took an average of NaNs (stddev NaN) to be included in an IB.
78+
INFO leios: sim_cli::events: Each transaction took an average of 22.520s (stddev 19.193) to be included in an EB.
79+
INFO leios: sim_cli::events: Each transaction took an average of 48.975s (stddev 27.799) to be included in a block.
80+
INFO network: sim_cli::events: 67410749 TX message(s) were sent. 67410749 of them were received (100.000%).
81+
INFO network: sim_cli::events: 0 IB message(s) were sent. 0 of them were received (NaN%).
82+
INFO network: sim_cli::events: 38535 EB message(s) were sent. 38535 of them were received (100.000%).
83+
INFO network: sim_cli::events: 6696809 Vote message(s) were sent. 6696809 of them were received (100.000%).
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Connectivity,Adversary,EB delay,Tx attack,Tx size,Throughput,Tx start [s],Tx stop [s],Sim stop [s]
2+
0.13,33% adversary,EB attack: 7.0 s/EB,Tx attack: 100%,1500 B/Tx,0.150 TxMB/s,60,960,1200

0 commit comments

Comments
 (0)