Skip to content

cmd/geth: add inspect trie tool to analysis trie storage#28892

Merged
lightclient merged 15 commits intoethereum:masterfrom
fynnss:inspect-trie
Feb 24, 2026
Merged

cmd/geth: add inspect trie tool to analysis trie storage#28892
lightclient merged 15 commits intoethereum:masterfrom
fynnss:inspect-trie

Conversation

@fynnss
Copy link
Copy Markdown
Contributor

@fynnss fynnss commented Jan 29, 2024

This pr adds a tool names inpsect-trie, aimed to analyze the mpt and its node storage more efficiently.

Example

./geth db inspect-trie --datadir server/data-seed/ latest 4000

Result

  • MPT shape
  • Account Trie
  • Top N Storage Trie
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      76      |     32      |      74      |
|   -   |   3   |      66      |      1      |      66      |
|   -   |   4   |      2       |      0      |      2       |
| Total |  144  |      50      |     142     |
+-------+-------+--------------+-------------+--------------+
AccountTrie
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |     108      |     84      |     104      |
|   -   |   3   |     195      |      5      |     195      |
|   -   |   4   |      10      |      0      |      10      |
| Total |  313  |     106      |     309     |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0xc874e65ccffb133d9db4ff637e62532ef6ecef3223845d02f522c55786782911
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      57      |     14      |      56      |
|   -   |   3   |      33      |      0      |      33      |
| Total |  90   |      31      |     89      |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0x1d7dcb6a0ce5227c5379fc5b0e004561d7833b063355f69bfea3178f08fbaab4
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      5       |      8      |      5       |
|   -   |   2   |      16      |      1      |      16      |
|   -   |   3   |      2       |      0      |      2       |
| Total |  23   |      10      |     23      |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0xaa8a4783ebbb3bec45d3e804b3c59bfd486edfa39cbeda1d42bf86c08a0ebc0f
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      9       |      3      |      9       |
|   -   |   2   |      7       |      1      |      7       |
|   -   |   3   |      2       |      0      |      2       |
| Total |  18   |      5       |     18      |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0x9d2804d0562391d7cfcfaf0013f0352e176a94403a58577ebf82168a21514441
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      6       |      4      |      6       |
|   -   |   2   |      8       |      0      |      8       |
| Total |  14   |      5       |     14      |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0x17e3eb95d0e6e92b42c0b3e95c6e75080c9fcd83e706344712e9587375de96e1
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      5       |      3      |      5       |
|   -   |   2   |      7       |      0      |      7       |
| Total |  12   |      4       |     12      |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0xc017ca90c8aa37693c38f80436bb15bde46d7b30a503aa808cb7814127468a44
Contract Trie, total trie num: 142, ShortNodeCnt: 620, FullNodeCnt: 204, ValueNodeCnt: 615

@MariusVanDerWijden
Copy link
Copy Markdown
Member

This PR on mainnet:

+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      0       |     256     |      0       |
|   -   |   3   |      0       |    4096     |      0       |
|   -   |   4   |      0       |    65536    |      0       |
|   -   |   5   |      0       |   1048576   |      0       |
|   -   |   6   |     438      |  16776930   |     263      |
|   -   |   7   |  100144570   |  56122080   |   97505275   |
|   -   |   8   |  124204988   |   3221357   |  124000341   |
|   -   |   9   |   6480231    |    10439    |   6479228    |
|   -   |  10   |    20884     |      2      |    20883     |
|   -   |  11   |      4       |      0      |      4       |
| Total |   -   |  230851115   |  77249289   |  228005994   |
+-------+-------+--------------+-------------+--------------+
AccountTrie
EOA accounts num:  190618297
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      0       |     256     |      0       |
|   -   |   3   |      0       |    4096     |      0       |
|   -   |   4   |      0       |    65536    |      0       |
|   -   |   5   |      0       |   1048576   |      0       |
|   -   |   6   |   2632166    |  13611933   |   2388687    |
|   -   |   7   |   40897826   |   4112954   |   40656890   |
|   -   |   8   |   8404095    |    48282    |   8401135    |
|   -   |   9   |    96671     |     48      |    96668     |
|   -   |  10   |      96      |      0      |      96      |
| Total |   -   |   52030854   |  18891698   |   51543476   |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0x159e4890cde46d5cadbfcd08a052f495ae791244728e06d910cc743ed05eae12
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      0       |     256     |      0       |
|   -   |   3   |      0       |    4096     |      0       |
|   -   |   4   |      0       |    65536    |      0       |
|   -   |   5   |      0       |   1048576   |      0       |
|   -   |   6   |   6267714    |   5853598   |   6029411    |
|   -   |   7   |   13620075   |   519213    |   13588531   |
|   -   |   8   |   1047203    |    2323     |   1047042    |
|   -   |   9   |     4648     |      0      |     4648     |
| Total |   -   |   20939640   |   7493615   |   20669632   |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0xfe1c2c3bf003e59420de2a964984544a947ac6de636a2dedb89b689ab278b65e
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      0       |     256     |      0       |
|   -   |   3   |      0       |    4096     |      0       |
|   -   |   4   |      0       |    65536    |      0       |
|   -   |   5   |      5       |   1048574   |      2       |
|   -   |   6   |   6360087    |   4255479   |   6169042    |
|   -   |   7   |   9567427    |   284426    |   9549861    |
|   -   |   8   |    572674    |    1007     |    572609    |
|   -   |   9   |     2016     |      0      |     2016     |
| Total |   -   |   16502209   |   5659391   |   16293530   |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0xfbd1592b616670c3c966b8ed9942aecdb2b25ab10837f7d1c8d1e66c10f243a8
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      0       |     256     |      0       |
|   -   |   3   |      0       |    4096     |      0       |
|   -   |   4   |      0       |    65536    |      0       |
|   -   |   5   |      10      |   1048568   |      8       |
|   -   |   6   |   6345222    |   4047200   |   6161871    |
|   -   |   7   |   9060682    |   259799    |   9044727    |
|   -   |   8   |    522892    |     917     |    522841    |
|   -   |   9   |     1834     |      0      |     1834     |
| Total |   -   |   15930640   |   5426389   |   15731281   |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0x4e6f19bdf5c8f4aa5e46a382f33fbed981bd7d93c25885c5ecdabfdc102f8b67
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      0       |     256     |      0       |
|   -   |   3   |      0       |    4096     |      0       |
|   -   |   4   |      0       |    65536    |      0       |
|   -   |   5   |      53      |   1048541   |      31      |
|   -   |   6   |   6191387    |   3228255   |   6037188    |
|   -   |   7   |   7104178    |   173532    |   7093403    |
|   -   |   8   |    348985    |     493     |    348948    |
|   -   |   9   |     986      |      0      |     986      |
| Total |   -   |   13645589   |   4520726   |   13480556   |
+-------+-------+--------------+-------------+--------------+
ContractTrie-0x9f13f88230a70de90ed5fa41ba35a5fb78bc55d11cc9406f17d314fb67047ac7

@fynnss
Copy link
Copy Markdown
Contributor Author

fynnss commented Jan 30, 2024

Nice job! @MariusVanDerWijden

Currently, only the hash of the contract address can be printed. The contract address can be obtained through the preimage.

Comment thread cmd/geth/dbcmd.go Outdated
Comment thread cmd/geth/dbcmd.go Outdated
Comment thread cmd/geth/dbcmd.go Outdated
Comment thread cmd/geth/dbcmd.go Outdated
Comment thread cmd/geth/dbcmd.go Outdated
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
@fynnss fynnss force-pushed the inspect-trie branch 2 times, most recently from 3bdeec1 to 1581066 Compare January 31, 2024 11:48
@fynnss fynnss requested a review from holiman January 31, 2024 13:00
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
Comment thread trie/inspect_trie.go Outdated
@MariusVanDerWijden
Copy link
Copy Markdown
Member

Still getting killed with OOM for me...

Inspected 3834181111 trie nodes in 10h8m32.000775427s
Inspected 3834883531 trie nodes in 10h8m40.000154241s
+-------+-------+--------------+-------------+--------------+
|   -   | LEVEL | SHORTNODECNT | FULLNODECNT | VALUENODECNT |
+-------+-------+--------------+-------------+--------------+
|   -   |   0   |      0       |      1      |      0       |
|   -   |   1   |      0       |     16      |      0       |
|   -   |   2   |      0       |     256     |      0       |
|   -   |   3   |      0       |    4096     |      0       |
|   -   |   4   |      0       |    65536    |      0       |
|   -   |   5   |      0       |   1048576   |      0       |
|   -   |   6   |      8       |  16777213   |      3       |
|   -   |   7   |  101606337   |  82780951   |   98088636   |
|   -   |   8   |  189771140   |   6555308   |  189363030   |
|   -   |   9   |   13212109   |    27657    |   13209879   |
|   -   |  10   |    55340     |     10      |    55337     |
|   -   |  11   |      20      |      0      |      20      |
| Total |   -   |  304644954   |  107259620  |  300716905   |
+-------+-------+--------------+-------------+--------------+
AccountTrie
``

@lightclient lightclient self-assigned this Sep 24, 2025
@gballet gballet self-assigned this Sep 29, 2025
@gballet gballet added this to the 1.16.6 milestone Oct 16, 2025
Copy link
Copy Markdown
Member

@gballet gballet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few comments. Regarding verkle/binary, I can add support for it later.

Comment thread trie/inspect.go Outdated
Comment on lines +184 to +191
// triestat tracks the type and count of trie nodes at each level in the trie.
//
// Note: theoretically it is possible to have up to 64 trie level. Since it is
// unlikely to encounter such a large trie, the stats are capped at 16 levels to
// avoid substantial unneeded allocation.
type triestat struct {
level [16]stat
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a similar structure in core/stateless/stats, it should be merged.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me look into this.

Comment thread core/rawdb/database.go
}

table := newTableWriter(os.Stdout)
table := tablewriter.NewWriter(os.Stdout)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the point of moving this to its own package, the tree writer is only used in trie, which is the one importing rawdb.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it to it's own package because it isn't exported from rawdb. It felt wrong to expose it publicly in that package.

@fjl fjl modified the milestones: 1.16.6, 1.16.8 Nov 4, 2025
Co-authored-by: Fynn <zcheng1004@gmail.com>
Co-authored-by: lightclient <lightclient@protonmail.com>
Co-authored-by: MariusVanDerWijden <m.vanderwijden@live.de>
@MariusVanDerWijden MariusVanDerWijden changed the title cmd/dbcmd: add inspect trie tool to analysis trie storage cmd/geth: add inspect trie tool to analysis trie storage Jan 7, 2026
@MariusVanDerWijden
Copy link
Copy Markdown
Member

I've rebase the PR on top of master and added optional JSON output, because that would be very beneficial for the Pandaops team, who would like to use this to display the current state of the trie on their website

@gballet
Copy link
Copy Markdown
Member

gballet commented Jan 29, 2026

@lightclient can we review this again?

@lightclient
Copy link
Copy Markdown
Member

lightclient commented Feb 17, 2026

Two main things have been blocking this PR:

  1. Integrating triestat into WitnessStats per review comment by @gballet. This was addressed in 97cdc16, so PTAL.
  2. Fix OOM on large state tries.

I confirmed that this PR still OOMs on mainnet with 16GB memory. Currently testing a new 2-pass strategy for the inspector. Instead of keeping trie stats in memory, we'll just flush each goroutine's result (i.e. the stat for a specific storage trie) to disk then come back in a second pass and do the summarization where we determine the top N to print.

The streamed file should only be 8-12 GB on disk, so not a heavy lift. Will update with the results from that test.

Comment thread trie/levelstats.go Outdated
Comment thread trie/inspect.go
var ret error
if in.dumpBuf != nil {
if err := in.dumpBuf.Flush(); err != nil {
ret = errors.Join(ret, fmt.Errorf("failed to flush trie dump %s: %w", in.config.DumpPath, err))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need to call Join here?

@lightclient
Copy link
Copy Markdown
Member

Okay was able to run the PR against mainnet. OOM is generally solved via streaming storage trie results to disk and executing a second pass over them at the end, which takes less than 1 second on mainnet.

Mainnet inspect-trie results
Ran against mainnet state at block **24,397,789** on `geth-ai-experiments-01`. Full run completed in ~9 hours. Dump file is 5.3 GB (25,223,117 records × 224 bytes, cleanly divisible).

Account Trie

Level Short Nodes Full Nodes Value Nodes
0 0 1 0
1 0 16 0
2 0 256 0
3 0 4,096 0
4 0 65,536 0
5 0 1,048,576 0
6 0 16,777,216 0
7 98,492,127 98,856,709 0
8 234,386,577 13,411,676 94,455,279
9 27,082,034 681,162 233,770,042
10 1,363,076 5,383 27,076,859
11 10,766 68 1,363,008
12 136 0 10,766
13 0 0 136
Total 361,334,716 130,850,695 356,676,090

Max depth 13. 848,861,501 total nodes.

Storage Summary

Metric Value
Total storage tries 25,223,116
Aggregate short nodes 1,482,547,385
Aggregate full nodes 502,430,568
Aggregate value nodes 1,467,040,910
Total storage nodes 3,452,018,863

Storage Trie Depth Distribution

Depth Count %
0 3,299 0.01%
1 13,854,311 54.93%
2 7,342,891 29.11%
3 2,726,606 10.81%
4 839,848 3.33%
5 288,551 1.14%
6 115,698 0.46%
7 38,700 0.15%
8 10,908 0.04%
9 2,018 0.01%
10 244 <0.01%
11 38 <0.01%
12 4 <0.01%

84% of storage tries have depth ≤ 2. Only 4 reach depth 12.

Top 10 Storage Tries (by total node count)

# Owner Total Nodes Value Nodes Depth
1 0x159e4890... 283,507,272 121,694,343 12
2 0xab14d688... 51,820,655 21,785,464 12
3 0xfe1c2c3b... 49,103,002 20,669,677 12
4 0xfbd1592b... 38,458,576 16,294,950 11
5 0x4e6f19bd... 37,088,457 15,731,344 11
6 0x1ff0800a... 35,175,919 14,881,511 12
7 0x9f13f882... 31,644,586 13,479,602 11
8 0x7b5855bb... 31,011,444 13,216,761 11
9 0x13e5221b... 25,313,379 10,836,537 11
10 0x0e02bb4c... 23,307,994 9,991,466 11

Owner 0x159e4890... alone holds 8.2% of all storage nodes (283M of 3.45B).

Dump file

Metric Value
Size 5,649,978,208 bytes (5.3 GB)
Record size 224 bytes
Total records 25,223,117
Remainder 0

@lightclient
Copy link
Copy Markdown
Member

lightclient commented Feb 23, 2026

Some updated tables, especially with the --contract mode like #33721 introduced.

Contract mode output

--contract mode output

USDT (0xdAC17F958D2ee523a2206206994597C13D831ec7)

~52M trie nodes, completes in ~5 minutes.

=== Contract Inspection: 0xdAC17F958D2ee523a2206206994597C13D831ec7 ===
Account hash: 0xab14d68802a763f7db875346d03fbf86f137de55814b191c069e721f47474733

Account snapshot: 70.00 B
Snapshot storage: 21796253 slots (1.60 GiB)
Storage trie:     51820655 nodes (1.98 GiB)

Storage Trie Depth Distribution:
+-------+----------+---------+----------+----------+------------+
| Depth |  Short   |  Full   |  Value   |  Nodes   |    Size    |
+-------+----------+---------+----------+----------+------------+
|   0   |    0     |    1    |    0     |    1     |  532.00 B  |
|   1   |    0     |   16    |    0     |    16    |  8.31 KiB  |
|   2   |    0     |   256   |    0     |   256    | 133.00 KiB |
|   3   |    0     |  4096   |    0     |   4096   |  2.08 MiB  |
|   4   |    0     |  65536  |    0     |  65536   | 33.25 MiB  |
|   5   |    0     | 1048576 |    0     | 1048576  | 392.24 MiB |
|   6   | 6193871  | 6004155 |    0     | 12198026 | 833.34 MiB |
|   7   | 14175491 | 802808  | 5945581  | 20923880 | 686.15 MiB |
|   8   | 1620617  |  39630  | 14139662 | 15799909 | 74.17 MiB  |
|   9   |  79325   |   270   | 1620355  | 1699950  |  3.28 MiB  |
|  10   |   540    |    1    |  79324   |  79865   | 23.04 KiB  |
|  11   |    2     |    0    |   540    |   542    |  77.00 B   |
|  12   |    0     |    0    |    2     |    2     |   0.00 B   |

WETH (0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)

~16M trie nodes, completes in ~1.5 minutes.

=== Contract Inspection: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ===
Account hash: 0x8679e8eda65bd257638cf8cf09b8238888947cc3c0bea2aa2cc3f1c4ac7a3002

Account snapshot: 81.00 B
Snapshot storage: 6857849 slots (547.64 MiB)
Storage trie:     15981519 nodes (657.67 MiB)

Storage Trie Depth Distribution:
+-------+---------+---------+---------+---------+------------+
| Depth |  Short  |  Full   |  Value  |  Nodes  |    Size    |
+-------+---------+---------+---------+---------+------------+
|   0   |    0    |    1    |    0    |    1    |  532.00 B  |
|   1   |    0    |   16    |    0    |   16    |  8.31 KiB  |
|   2   |    0    |   256   |    0    |   256   | 133.00 KiB |
|   3   |    0    |  4096   |    0    |  4096   |  2.08 MiB  |
|   4   |    0    |  65536  |    0    |  65536  | 33.20 MiB  |
|   5   |  12242  | 1034845 |    0    | 1047087 | 190.86 MiB |
|   6   | 4605296 | 1013611 |  9943   | 5628850 | 312.29 MiB |
|   7   | 2129845 |  84196  | 4546687 | 6760728 | 110.57 MiB |
|   8   | 168899  |  1789   | 2128164 | 2298852 |  8.37 MiB  |
|   9   |  3579   |   10    | 168889  | 172478  | 172.95 KiB |
|  10   |   20    |    0    |  3579   |  3599   | 1002.00 B  |
|  11   |    0    |    0    |   20    |   20    |   0.00 B   |

Largest mainnet contract (0x06450dEe7FD2Fb8E39061434BAbCFC05599a6Fb8)

~328M trie nodes, completes in ~30 minutes.

=== Contract Inspection: 0x06450dEe7FD2Fb8E39061434BAbCFC05599a6Fb8 ===
Account hash: 0x159e4890cde46d5cadbfcd08a052f495ae791244728e06d910cc743ed05eae12

Account snapshot: 70.00 B
Snapshot storage: 140981217 slots (9.50 GiB)
Storage trie:     328433262 nodes (11.55 GiB)

Storage Trie Depth Distribution:
+-------+----------+----------+----------+-----------+------------+
| Depth |  Short   |   Full   |  Value   |   Nodes   |    Size    |
+-------+----------+----------+----------+-----------+------------+
|   0   |    0     |    1     |    0     |     1     |  532.00 B  |
|   1   |    0     |    16    |    0     |    16     |  8.31 KiB  |
|   2   |    0     |   256    |    0     |    256    | 133.00 KiB |
|   3   |    0     |   4096   |    0     |   4096    |  2.08 MiB  |
|   4   |    0     |  65536   |    0     |   65536   | 33.25 MiB  |
|   5   |    0     | 1048576  |    0     |  1048576  | 531.88 MiB |
|   6   |  41464   | 16731979 |    0     | 16773443  |  3.57 GiB  |
|   7   | 84724248 | 24910077 |  31413   | 109665738 |  5.15 GiB  |
|   8   | 53107849 | 2209535  | 83341277 | 138658661 |  2.12 GiB  |
|   9   | 4435316  |  58304   | 53053648 | 57547268  | 165.43 MiB |
|  10   |  116639  |   268    | 4435053  |  4551960  |  4.25 MiB  |
|  11   |   536    |    0     |  116639  |  117175   | 19.45 KiB  |
|  12   |    0     |    0     |   536    |    536    |   0.00 B   |

Normal inspect-trie output (no --contract flag)

Full trie walk at the same block (24,397,789). Takes ~8–9 hours.

Combined depth distribution

Trie Depth Distribution
Account Trie: 848861501 nodes (52.59 GiB)
Storage Tries: 3487227070 nodes (130.98 GiB) across 25223116 tries
+-------+---------------+--------------+---------------+--------------+
| Depth | Account Nodes | Account Size | Storage Nodes | Storage Size |
+-------+---------------+--------------+---------------+--------------+
|   0   |       1       |   532.00 B   |   25223116    |   2.70 GiB   |
|   1   |      16       |   8.31 KiB   |   72653844    |   5.07 GiB   |
|   2   |      256      |  133.00 KiB  |   134789067   |  10.06 GiB   |
|   3   |     4096      |   2.08 MiB   |   282347669   |  20.40 GiB   |
|   4   |     65536     |  33.25 MiB   |   560338756   |  28.61 GiB   |
|   5   |    1048576    |  532.00 MiB  |   755823403   |  27.89 GiB   |
|   6   |   16777216    |   6.19 GiB   |   738291805   |  22.49 GiB   |
|   7   |   197348836   |  18.57 GiB   |   566022240   |  11.03 GiB   |
|   8   |   342253532   |  24.40 GiB   |   279111223   |   2.55 GiB   |
|   9   |   261533238   |   2.73 GiB   |   67706907    |  173.71 MiB  |
|  10   |   28445318    |  138.29 MiB  |    4802813    |   4.19 MiB   |
|  11   |    1373842    |   1.08 MiB   |    115695     |  19.36 KiB   |
|  12   |     10902     |  13.64 KiB   |      532      |    0.00 B    |
|  13   |      136      |    0.00 B    |       0       |    0.00 B    |

Account trie detail

+---------------+-------+-------------+-----------+------------+
| Accounts trie | Level | Short Nodes | Full Node | Value Node |
+---------------+-------+-------------+-----------+------------+
|       -       |   0   |      0      |     1     |     0      |
|       -       |   1   |      0      |    16     |     0      |
|       -       |   2   |      0      |    256    |     0      |
|       -       |   3   |      0      |   4096    |     0      |
|       -       |   4   |      0      |   65536   |     0      |
|       -       |   5   |      0      |  1048576  |     0      |
|       -       |   6   |      0      | 16777216  |     0      |
|       -       |   7   |  98492127   | 98856709  |     0      |
|       -       |   8   |  234386577  | 13411676  |  94455279  |
|       -       |   9   |  27082034   |  681162   | 233770042  |
|       -       |  10   |   1363076   |   5383    |  27076859  |
|       -       |  11   |    10766    |    68     |  1363008   |
|       -       |  12   |     136     |     0     |   10766    |
|       -       |  13   |      0      |     0     |    136     |
+---------------+-------+-------------+-----------+------------+
|     Total     |       |  361334716  | 130850695 | 356676090  |
+---------------+-------+-------------+-----------+------------+
Max depth 13

Storage trie aggregate summary

Storage trie aggregate summary
Total storage tries: 25223116
Total nodes: 3487227070
Total size: 130.98 GiB
  Short nodes: 1497802873
  Full nodes:  507282860
  Value nodes: 1482141337

Storage trie depth histogram

+-----------+---------------+
| Max Depth | Storage Tries |
+-----------+---------------+
|     0     |     2411      |
|     1     |   13854311    |
|     2     |    7343580    |
|     3     |    2726634    |
|     4     |    839969     |
|     5     |    288573     |
|     6     |    115719     |
|     7     |     38705     |
|     8     |     10909     |
|     9     |     2019      |
|    10     |      244      |
|    11     |      38       |
|    12     |       4       |
+-----------+---------------+

Top storage tries by node count (excerpt: #1 and #2)

1: 0x159e4890cde46d5cadbfcd08a052f495ae791244728e06d910cc743ed05eae12
+--------------+-------+-------------+-----------+------------+
| storage trie | Level | Short Nodes | Full Node | Value Node |
+--------------+-------+-------------+-----------+------------+
|      -       |   0   |      0      |     1     |     0      |
|      -       |   1   |      0      |    15     |     0      |
|      -       |   2   |      0      |    247    |     0      |
|      -       |   3   |      0      |   3959    |     0      |
|      -       |   4   |      0      |   63356   |     0      |
|      -       |   5   |      0      |  1013707  |     0      |
|      -       |   6   |    40085    | 16175591  |     0      |
|      -       |   7   |  81907482   | 24081074  |   30364    |
|      -       |   8   |  51340073   |  2136108  |  80570658  |
|      -       |   9   |   4287917   |   56419   |  51287631  |
|      -       |  10   |   112864    |    262    |  4287660   |
|      -       |  11   |     524     |     0     |   112864   |
|      -       |  12   |      0      |     0     |    524     |
+--------------+-------+-------------+-----------+------------+
|    Total     |       |  137688945  | 43530739  | 136289701  |
+--------------+-------+-------------+-----------+------------+
Max depth 12

2: 0xab14d68802a763f7db875346d03fbf86f137de55814b191c069e721f47474733
+--------------+-------+-------------+-----------+------------+
| storage trie | Level | Short Nodes | Full Node | Value Node |
+--------------+-------+-------------+-----------+------------+
|      -       |   0   |      0      |     1     |     0      |
|      -       |   1   |      0      |    16     |     0      |
|      -       |   2   |      0      |    256    |     0      |
|      -       |   3   |      0      |   4096    |     0      |
|      -       |   4   |      0      |   65536   |     0      |
|      -       |   5   |      0      |  1048576  |     0      |
|      -       |   6   |   6193871   |  6004155  |     0      |
|      -       |   7   |  14175491   |  802808   |  5945581   |
|      -       |   8   |   1620617   |   39630   |  14139662  |
|      -       |   9   |    79325    |    270    |  1620355   |
|      -       |  10   |     540     |     1     |   79324    |
|      -       |  11   |      2      |     0     |    540     |
|      -       |  12   |      0      |     0     |     2      |
+--------------+-------+-------------+-----------+------------+
|    Total     |       |  22069846   |  7965345  |  21785464  |
+--------------+-------+-------------+-----------+------------+
Max depth 12
</details>

lightclient
lightclient previously approved these changes Feb 24, 2026
Copy link
Copy Markdown
Member

@gballet gballet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I'm not a fan of dumping things into a gigabyte-sized intermediate file by default, but let's improve on the concept if the command turns out to be widely used.

@lightclient lightclient merged commit 8450e40 into ethereum:master Feb 24, 2026
10 of 12 checks passed
@7zkm7b8gw9-web
Copy link
Copy Markdown

Rad

SegueII added a commit to morph-l2/go-ethereum that referenced this pull request Apr 17, 2026
…8892)

Ports ethereum/go-ethereum#28892 to morph's v1.10.26-era trie package.
The implementation matches upstream's public API surface while adapting
to the differences in morph's trie opening / reader layer and to the
ZKTrie-aware chain config.

New building blocks
-------------------

trie/levelstats.go
  Per-depth classifier that counts short / full / value nodes and
  raw byte size per level, backed by atomic counters for concurrent
  writers. AddLeaf / LeafDepths preserve the witness-stats API so the
  same type can be reused by stateless verification if morph ever
  pulls in that path.

trie/inspect.go
  - Inspect(triedb, root, config): two-pass inspector. Pass 1 walks
    the account trie with bounded parallelism (16 concurrent walkers
    via semaphore.Weighted + errgroup), streams one fixed-size
    record per non-empty storage trie into a dump file on disk, and
    emits the account trie as a sentinel record. A ticker logs
    progress every 8s for long scans.
  - InspectContract(triedb, db, stateRoot, address): inspects a
    single contract's storage footprint by running the storage trie
    walk in parallel with an iterator over the snapshot storage
    prefix, so operators see both views side-by-side.
  - Summarize(dumpPath, config): pass 2 aggregates per-level totals,
    builds three top-N rankings (by max depth, total node count,
    value-node count), and emits a human-readable table via
    internal/tablewriter or a JSON blob when --output is supplied.
  - ErrUnsupportedTrieFormat signals ZKTrie-encoded state (morph
    pre-JadeFork) so the CLI can refuse before producing bogus
    statistics.

internal/tablewriter
  Self-contained text/tabwriter-backed stub mirroring the public API
  used by upstream's tablewriter call sites (SetHeader /
  AppendBulk / SetFooter / Render). Avoids pulling in a third-party
  dependency.

CLI surface (cmd/geth db inspect-trie)
--------------------------------------

  latest | <blocknum> | snapshot   select state root
  --exclude-storage                 skip per-account storage walks
  --top N                           top-N ranking size (default 10)
  --output <path>                   write JSON report instead of
                                    stdout tables
  --dump-path <path>                custom pass-1 dump location
                                    (default <datadir>/trie-dump.bin)
  --summarize <path>                re-summarize an existing dump,
                                    skipping the walk
  --contract 0xADDR                 run InspectContract against the
                                    resolved state root

Tests
-----

  TestInspectRoundTripsDump           — Inspect output and a
                                         standalone Summarize over
                                         the same dump produce
                                         byte-identical JSON.
  TestInspectNoStorageSkipsWalk       — NoStorage short-circuits the
                                         storage walk but still
                                         emits the account sentinel.
  TestInspectEmptyRootEmitsAccountSentinel
                                      — one 352-byte record on an
                                         empty trie.
  TestInspectRejectsMissingRoot       — clean error on unknown root.
  TestSummarizeRejectsTruncatedDump   — dump file size validation.
  TestSummarizeRejectsMissingAccountSentinel
                                      — sentinel record is mandatory.
  TestInspectContract                 — end-to-end run on a synthetic
                                         contract with snapshot data.
  TestInspectContractRejectsMissingAccount /
    TestInspectContractRejectsStorageless
                                      — refuse absent or empty
                                         storage tries.
  Level-stats + tablewriter unit tests round out the bucket.

Intentionally out of scope
--------------------------

  - core/stateless/stats.go does not currently use LevelStats on
    morph; migrating it is a separate change that can follow once
    stateless verification tracks upstream more closely.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants