Skip to content

Commit 3a5a3c1

Browse files
authored
Plutus experiment (#479)
* Designed plutus experiment * Completed analysis * Updated logbook
1 parent 6f63808 commit 3a5a3c1

40 files changed

+4890
-0
lines changed

Logbook.md

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

3+
## 2025-08-04
4+
5+
### Experiment varying Plutus validation time
6+
7+
8+
The Jupyter notebook [analysis/sims/2025w31c/analysis.ipynb](analysis/sims/2025w31c/analysis.ipynb) varies the CPU time used by Plutus phase 2 validation in Linear Leios at 100 TPS for a 6-vCPU node.
9+
10+
- Simulation with 6-vCPU nodes supported doubling the Plutus per-transaction budget on Linear Leios.
11+
- Simulations at a sixfold increase in the Plutus per-transaction budget failed: nodes bogged down validating transactions and cannot put them in new EBs.
12+
- EB could likely handle 5000 Gstep of Plutus computation in Linear Leios, which is 250x the Praos per-block budget.
13+
- This could support a handful of Plutus transactions with a 20x greater Plutus budget.
14+
- Alternatively every Plutus transaction could have its budget increased by 50%.
15+
- However, intentionally late diffusion of Plutus-heavy transactions could interfere with EB adoption.
16+
- These results are uncertain due to the variability in measured Plutus CPU costs: there is quite a bit of variability in the CPU time actually used by a Plutus script given its execution steps.
17+
318
## 2025-08-01
419

520
### Comparison of Haskell and Rust simulations of Linear Leios

analysis/sims/2025w31c/analysis.ipynb

Lines changed: 3047 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/{1,3,10,30,100}.00 -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.33
17+
fi
18+
(
19+
echo "$HL,$HR"
20+
for g in $(find experiments/{1,3,10,30,100}.00 -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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
experiments/0.030/run.sh
2+
experiments/0.100/run.sh
3+
experiments/0.300/run.sh
4+
experiments/1.000/run.sh
5+
experiments/3.000/run.sh
6+
experiments/10.000/run.sh
7+
experiments/30.000/run.sh
8+
experiments/100.000/run.sh
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Simulator,Variant,Network,Bandwidth,Stage length,EB rate,Max EB size,Tx size,Throughput,Tx start [s],Tx stop [s],Sim stop [s],Tx validation
2+
Rust,linear-with-tx-references,topology-v2,50 Mb/s,8 slot/stage,2.5 EB/stage,10 MB/EB,1500 B/Tx,0.150 TxMB/s,60,960,1200,0.03 ms/Tx
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"relay-strategy": "request-from-first",
3+
"tcp-congestion-control": true,
4+
"multiplex-mini-protocols": true,
5+
"simulate-transactions": true,
6+
"treat-blocks-as-full": false,
7+
"cleanup-policies": [
8+
"cleanup-expired-vote"
9+
],
10+
"timestamp-resolution-ms": 0.1,
11+
"leios-variant": "linear-with-tx-references",
12+
"linear-vote-stage-length-slots": 8,
13+
"linear-diffuse-stage-length-slots": 8,
14+
"leios-stage-length-slots": 8,
15+
"leios-stage-active-voting-slots": 1,
16+
"leios-vote-send-recv-stages": false,
17+
"leios-late-ib-inclusion": true,
18+
"leios-header-diffusion-time-ms": 1000.0,
19+
"leios-mempool-sampling-strategy": "ordered-by-id",
20+
"leios-mempool-aggressive-pruning": true,
21+
"praos-chain-quality": 100,
22+
"praos-fallback-enabled": true,
23+
"tx-generation-distribution": {
24+
"distribution": "constant",
25+
"value": 10
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.030,
37+
"tx-max-size-bytes": 16384,
38+
"tx-start-time": 60,
39+
"tx-stop-time": 960,
40+
"rb-generation-probability": 0.05,
41+
"rb-head-size-bytes": 1024,
42+
"rb-body-max-size-bytes": 90112,
43+
"rb-generation-cpu-time-ms": 1.0,
44+
"rb-head-validation-cpu-time-ms": 1.0,
45+
"rb-body-legacy-praos-payload-avg-size-bytes": 0,
46+
"rb-body-legacy-praos-payload-validation-cpu-time-ms-constant": 50.0,
47+
"rb-body-legacy-praos-payload-validation-cpu-time-ms-per-byte": 0.0005,
48+
"ib-generation-probability": 2.0,
49+
"ib-shards": 1,
50+
"ib-shard-period-length-slots": 1,
51+
"ib-shard-group-count": 1,
52+
"ib-head-size-bytes": 304,
53+
"ib-body-avg-size-bytes": 98304,
54+
"ib-body-max-size-bytes": 262144,
55+
"ib-generation-cpu-time-ms": 130.0,
56+
"ib-head-validation-cpu-time-ms": 1.0,
57+
"ib-body-validation-cpu-time-ms-constant": 50.0,
58+
"ib-body-validation-cpu-time-ms-per-byte": 0.0005,
59+
"ib-diffusion-strategy": "freshest-first",
60+
"ib-diffusion-max-bodies-to-request": 1,
61+
"ib-diffusion-max-headers-to-request": 100,
62+
"ib-diffusion-max-window-size": 100,
63+
"eb-generation-probability": 2.5,
64+
"eb-size-bytes-constant": 240,
65+
"eb-size-bytes-per-ib": 32,
66+
"eb-generation-cpu-time-ms": 75.0,
67+
"eb-validation-cpu-time-ms": 1.0,
68+
"eb-diffusion-strategy": "peer-order",
69+
"eb-diffusion-max-bodies-to-request": 1,
70+
"eb-diffusion-max-headers-to-request": 100,
71+
"eb-diffusion-max-window-size": 100,
72+
"eb-max-age-slots": 240,
73+
"eb-max-age-for-relay-slots": 40,
74+
"eb-referenced-txs-max-size-bytes": 10000000,
75+
"eb-body-avg-size-bytes": 10000000,
76+
"vote-generation-probability": 500.0,
77+
"vote-threshold": 300,
78+
"vote-generation-cpu-time-ms-constant": 0.164,
79+
"vote-generation-cpu-time-ms-per-ib": 0,
80+
"vote-validation-cpu-time-ms": 0.816,
81+
"vote-bundle-size-bytes-constant": 0,
82+
"vote-bundle-size-bytes-per-eb": 105,
83+
"vote-diffusion-strategy": "peer-order",
84+
"vote-diffusion-max-bodies-to-request": 1,
85+
"vote-diffusion-max-headers-to-request": 100,
86+
"vote-diffusion-max-window-size": 100,
87+
"cert-size-bytes-constant": 7168,
88+
"cert-size-bytes-per-node": 0,
89+
"cert-generation-cpu-time-ms-constant": 90.0,
90+
"cert-generation-cpu-time-ms-per-node": 0,
91+
"cert-validation-cpu-time-ms-constant": 130.0,
92+
"cert-validation-cpu-time-ms-per-node": 0
93+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../run.sh
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
INFO praos: sim_cli::events: 90001 transactions(s) were generated in total.
2+
INFO praos: sim_cli::events: 56 naive praos block(s) were published.
3+
INFO praos: sim_cli::events: 1144 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 0 published 1 naive praos block(s)
7+
INFO praos: sim_cli::events: Pool 4 published 2 naive praos block(s)
8+
INFO praos: sim_cli::events: Pool 35 published 0 naive praos block(s)
9+
INFO praos: sim_cli::events: Pool 35 failed to publish 1 naive praos block(s) due to slot battles.
10+
INFO praos: sim_cli::events: Pool 37 published 1 naive praos block(s)
11+
INFO praos: sim_cli::events: Pool 40 published 1 naive praos block(s)
12+
INFO praos: sim_cli::events: Pool 41 published 2 naive praos block(s)
13+
INFO praos: sim_cli::events: Pool 46 published 1 naive praos block(s)
14+
INFO praos: sim_cli::events: Pool 53 published 1 naive praos block(s)
15+
INFO praos: sim_cli::events: Pool 55 published 1 naive praos block(s)
16+
INFO praos: sim_cli::events: Pool 56 published 1 naive praos block(s)
17+
INFO praos: sim_cli::events: Pool 65 published 1 naive praos block(s)
18+
INFO praos: sim_cli::events: Pool 68 published 1 naive praos block(s)
19+
INFO praos: sim_cli::events: Pool 73 published 1 naive praos block(s)
20+
INFO praos: sim_cli::events: Pool 81 published 1 naive praos block(s)
21+
INFO praos: sim_cli::events: Pool 97 published 1 naive praos block(s)
22+
INFO praos: sim_cli::events: Pool 121 published 1 naive praos block(s)
23+
INFO praos: sim_cli::events: Pool 123 published 1 naive praos block(s)
24+
INFO praos: sim_cli::events: Pool 129 published 1 naive praos block(s)
25+
INFO praos: sim_cli::events: Pool 136 published 1 naive praos block(s)
26+
INFO praos: sim_cli::events: Pool 353 published 1 naive praos block(s)
27+
INFO praos: sim_cli::events: Pool 361 published 1 naive praos block(s)
28+
INFO praos: sim_cli::events: Pool 362 published 1 naive praos block(s)
29+
INFO praos: sim_cli::events: Pool 367 published 2 naive praos block(s)
30+
INFO praos: sim_cli::events: Pool 371 published 1 naive praos block(s)
31+
INFO praos: sim_cli::events: Pool 376 published 1 naive praos block(s)
32+
INFO praos: sim_cli::events: Pool 377 published 1 naive praos block(s)
33+
INFO praos: sim_cli::events: Pool 418 published 3 naive praos block(s)
34+
INFO praos: sim_cli::events: Pool 419 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 443 published 2 naive praos block(s)
37+
INFO praos: sim_cli::events: Pool 474 published 1 naive praos block(s)
38+
INFO praos: sim_cli::events: Pool 478 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 517 published 1 naive praos block(s)
41+
INFO praos: sim_cli::events: Pool 520 published 1 naive praos block(s)
42+
INFO praos: sim_cli::events: Pool 521 published 1 naive praos block(s)
43+
INFO praos: sim_cli::events: Pool 527 published 2 naive praos block(s)
44+
INFO praos: sim_cli::events: Pool 533 published 1 naive praos block(s)
45+
INFO praos: sim_cli::events: Pool 536 published 1 naive praos block(s)
46+
INFO praos: sim_cli::events: Pool 537 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 541 published 1 naive praos block(s)
49+
INFO praos: sim_cli::events: Pool 554 published 1 naive praos block(s)
50+
INFO praos: sim_cli::events: Pool 561 published 1 naive praos block(s)
51+
INFO praos: sim_cli::events: Pool 563 published 1 naive praos block(s)
52+
INFO praos: sim_cli::events: Pool 564 published 1 naive praos block(s)
53+
INFO praos: sim_cli::events: Pool 568 published 2 naive praos block(s)
54+
INFO praos: sim_cli::events: Pool 745 published 1 naive praos block(s)
55+
INFO praos: sim_cli::events: Pool 749 published 1 naive praos block(s)
56+
INFO leios: sim_cli::events: 0 IB(s) were generated, on average 0.000 IB(s) per slot.
57+
INFO leios: sim_cli::events: 0 out of 90001 transaction(s) were included in at least one IB.
58+
INFO leios: sim_cli::events: The average age of the pending transactions is NaNs (stddev NaN).
59+
INFO leios: sim_cli::events: Each transaction was included in an average of NaN IB(s) (stddev NaN).
60+
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.
61+
INFO leios: sim_cli::events: Each node received an average of 0.000 IB(s) (stddev 0.000).
62+
INFO leios: sim_cli::events: 57 EB(s) were generated; on average there were 0.048 EB(s) per slot.
63+
INFO leios: sim_cli::events: Each EB contained an average of 3039.789 transaction(s) (stddev 2402.123). 13 EB(s) were empty.
64+
INFO leios: sim_cli::events: Each EB contained an average of 0.000 IB(s) (stddev 0.000). 13 EB(s) were empty.
65+
INFO leios: sim_cli::events: Each IB was included in an average of NaN EB(s) (stddev NaN).
66+
INFO leios: sim_cli::events: 0 out of 0 IBs were included in at least one EB.
67+
INFO leios: sim_cli::events: 0 out of 0 IBs expired before they reached an EB.
68+
INFO leios: sim_cli::events: 21 out of 57 EBs expired before an EB from their stage reached an RB.
69+
INFO leios: sim_cli::events: 88561 out of 90001 transaction(s) were included in at least one EB.
70+
INFO leios: sim_cli::events: 25307 total votes were generated.
71+
INFO leios: sim_cli::events: Each stake pool produced an average of 117.162 vote(s) (stddev 23.192).
72+
INFO leios: sim_cli::events: Each EB received an average of 443.982 vote(s) (stddev 152.629).
73+
INFO leios: sim_cli::events: There were 9793 bundle(s) of votes. Each bundle contained 2.584 vote(s) (stddev 1.438).
74+
INFO leios: sim_cli::events: 31 L1 block(s) had a Leios endorsement.
75+
INFO leios: sim_cli::events: 87361 tx(s) (131.04 MB) were referenced by a Leios endorsement.
76+
INFO leios: sim_cli::events: 2640 tx(s) (3.96 MB) were included directly in a Praos block.
77+
INFO leios: sim_cli::events: Spatial efficiency: 131.04 MB/5.78 MB (2266.972%) of Leios bytes were unique transactions.
78+
INFO leios: sim_cli::events: 0 tx(s) (0.000%) referenced by a Leios endorsement were redundant.
79+
INFO leios: sim_cli::events: Each transaction took an average of NaNs (stddev NaN) to be included in an IB.
80+
INFO leios: sim_cli::events: Each transaction took an average of 22.743s (stddev 19.451) to be included in an EB.
81+
INFO leios: sim_cli::events: Each transaction took an average of 62.532s (stddev 30.424) to be included in a block.
82+
INFO network: sim_cli::events: 67410749 TX message(s) were sent. 67410749 of them were received (100.000%).
83+
INFO network: sim_cli::events: 0 IB message(s) were sent. 0 of them were received (NaN%).
84+
INFO network: sim_cli::events: 42349 EB message(s) were sent. 42349 of them were received (100.000%).
85+
INFO network: sim_cli::events: 7334957 Vote message(s) were sent. 7334957 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+
Simulator,Variant,Network,Bandwidth,Stage length,EB rate,Max EB size,Tx size,Throughput,Tx start [s],Tx stop [s],Sim stop [s],Tx validation
2+
Rust,linear-with-tx-references,topology-v2,50 Mb/s,8 slot/stage,2.5 EB/stage,10 MB/EB,1500 B/Tx,0.150 TxMB/s,60,960,1200,0.10 ms/Tx
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"relay-strategy": "request-from-first",
3+
"tcp-congestion-control": true,
4+
"multiplex-mini-protocols": true,
5+
"simulate-transactions": true,
6+
"treat-blocks-as-full": false,
7+
"cleanup-policies": [
8+
"cleanup-expired-vote"
9+
],
10+
"timestamp-resolution-ms": 0.1,
11+
"leios-variant": "linear-with-tx-references",
12+
"linear-vote-stage-length-slots": 8,
13+
"linear-diffuse-stage-length-slots": 8,
14+
"leios-stage-length-slots": 8,
15+
"leios-stage-active-voting-slots": 1,
16+
"leios-vote-send-recv-stages": false,
17+
"leios-late-ib-inclusion": true,
18+
"leios-header-diffusion-time-ms": 1000.0,
19+
"leios-mempool-sampling-strategy": "ordered-by-id",
20+
"leios-mempool-aggressive-pruning": true,
21+
"praos-chain-quality": 100,
22+
"praos-fallback-enabled": true,
23+
"tx-generation-distribution": {
24+
"distribution": "constant",
25+
"value": 10
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.100,
37+
"tx-max-size-bytes": 16384,
38+
"tx-start-time": 60,
39+
"tx-stop-time": 960,
40+
"rb-generation-probability": 0.05,
41+
"rb-head-size-bytes": 1024,
42+
"rb-body-max-size-bytes": 90112,
43+
"rb-generation-cpu-time-ms": 1.0,
44+
"rb-head-validation-cpu-time-ms": 1.0,
45+
"rb-body-legacy-praos-payload-avg-size-bytes": 0,
46+
"rb-body-legacy-praos-payload-validation-cpu-time-ms-constant": 50.0,
47+
"rb-body-legacy-praos-payload-validation-cpu-time-ms-per-byte": 0.0005,
48+
"ib-generation-probability": 2.0,
49+
"ib-shards": 1,
50+
"ib-shard-period-length-slots": 1,
51+
"ib-shard-group-count": 1,
52+
"ib-head-size-bytes": 304,
53+
"ib-body-avg-size-bytes": 98304,
54+
"ib-body-max-size-bytes": 262144,
55+
"ib-generation-cpu-time-ms": 130.0,
56+
"ib-head-validation-cpu-time-ms": 1.0,
57+
"ib-body-validation-cpu-time-ms-constant": 50.0,
58+
"ib-body-validation-cpu-time-ms-per-byte": 0.0005,
59+
"ib-diffusion-strategy": "freshest-first",
60+
"ib-diffusion-max-bodies-to-request": 1,
61+
"ib-diffusion-max-headers-to-request": 100,
62+
"ib-diffusion-max-window-size": 100,
63+
"eb-generation-probability": 2.5,
64+
"eb-size-bytes-constant": 240,
65+
"eb-size-bytes-per-ib": 32,
66+
"eb-generation-cpu-time-ms": 75.0,
67+
"eb-validation-cpu-time-ms": 1.0,
68+
"eb-diffusion-strategy": "peer-order",
69+
"eb-diffusion-max-bodies-to-request": 1,
70+
"eb-diffusion-max-headers-to-request": 100,
71+
"eb-diffusion-max-window-size": 100,
72+
"eb-max-age-slots": 240,
73+
"eb-max-age-for-relay-slots": 40,
74+
"eb-referenced-txs-max-size-bytes": 10000000,
75+
"eb-body-avg-size-bytes": 10000000,
76+
"vote-generation-probability": 500.0,
77+
"vote-threshold": 300,
78+
"vote-generation-cpu-time-ms-constant": 0.164,
79+
"vote-generation-cpu-time-ms-per-ib": 0,
80+
"vote-validation-cpu-time-ms": 0.816,
81+
"vote-bundle-size-bytes-constant": 0,
82+
"vote-bundle-size-bytes-per-eb": 105,
83+
"vote-diffusion-strategy": "peer-order",
84+
"vote-diffusion-max-bodies-to-request": 1,
85+
"vote-diffusion-max-headers-to-request": 100,
86+
"vote-diffusion-max-window-size": 100,
87+
"cert-size-bytes-constant": 7168,
88+
"cert-size-bytes-per-node": 0,
89+
"cert-generation-cpu-time-ms-constant": 90.0,
90+
"cert-generation-cpu-time-ms-per-node": 0,
91+
"cert-validation-cpu-time-ms-constant": 130.0,
92+
"cert-validation-cpu-time-ms-per-node": 0
93+
}

0 commit comments

Comments
 (0)