Skip to content

Conversation

@taratorio
Copy link
Member

@taratorio taratorio commented Jan 9, 2026

This PR fixes issues related to running the commitment backtester with the para trie v0 implementation (parallel only across the top row 16 nibbles)

The main issue that was fixed is a panic that occurred when using the same temporal read-only tx in different goroutines with API calls that involve a Cursor such as for GetAsOf (stack trace can be seen below). This was fixed by using a separate read-only transaction per goroutine in the para trie which was something I was planning on doing anyway.

Other minor fix included is that the para trie was not writing csv metrics files when enabled.

Now with this PR we are able to run the para trie in the backtester successfully using the --para-trie flag. In future PR I will add support for also running with pre-warmup with a --pre-warmup flag and additionally a cmd that will allow us to compare results between several backtest runs so that we can compare (sequential vs sequential-with-pre-warmup vs para-trie-v0 vs para-trie-v0-with-prewarmup).

panic: runtime error: cgo argument has Go pointer to unpinned Go pointer

goroutine 49 [running]:
github.com/erigontech/mdbx-go/mdbx.(*Cursor).getVal.func1(...)
	/Users/taratorio/go/pkg/mod/github.com/erigontech/[email protected]/mdbx/cursor.go:222
github.com/erigontech/mdbx-go/mdbx.(*Cursor).getVal(0x0?, {0x14002806bf8?, 0x1, 0x0?}, {0x14000b38780?, 0x8, 0x0?}, 0x3)
	/Users/taratorio/go/pkg/mod/github.com/erigontech/[email protected]/mdbx/cursor.go:223 +0xa4
github.com/erigontech/mdbx-go/mdbx.(*Cursor).Get(0x1400200ca70, {0x14002806bf8, 0x1, 0x1}, {0x14000b38780?, 0x0?, 0x0?}, 0x3)
	/Users/taratorio/go/pkg/mod/github.com/erigontech/[email protected]/mdbx/cursor.go:165 +0x3c
github.com/erigontech/erigon/db/kv/mdbx.(*MdbxDupSortCursor).SeekBothRange(0x140014081f8, {0x14002806bf8?, 0x74000b9cd20?, 0x0?}, {0x14000b38780?, 0x0?, 0x0?})
	/Users/taratorio/erigon/db/kv/mdbx/kv_mdbx.go:1437 +0x34
github.com/erigontech/erigon/db/state.(*HistoryRoTx).historySeekInDB(0x14000050d80, {0x14002806bf8, 0x1, 0x1}, 0x303f9e1, {0x10397e420?, 0x74000b9cd20?})
	/Users/taratorio/erigon/db/state/history.go:1240 +0x25c
github.com/erigontech/erigon/db/state.(*HistoryRoTx).HistorySeek(0x14000050d80, {0x14002806bf8, 0x1, 0x1}, 0x303f9e1, {0x10397e420, 0x74000b9cd20})
	/Users/taratorio/erigon/db/state/history.go:1192 +0x94
github.com/erigontech/erigon/db/state.(*DomainRoTx).GetAsOf(0x14001ed2340, {0x14002806bf8, 0x1, 0x1}, 0x303f9e1, {0x10397e420, 0x74000b9cd20})
	/Users/taratorio/erigon/db/state/domain.go:1440 +0x64
github.com/erigontech/erigon/db/state.(*AggregatorRoTx).GetAsOf(0x4400177e180, 0x3, {0x14002806bf8, 0x1, 0x1}, 0x1006ecefc?, {0x10397e420, 0x74000b9cd20})
	/Users/taratorio/erigon/db/state/aggregator.go:1822 +0x74
github.com/erigontech/erigon/db/kv/temporal.(*tx).getAsOf(...)
	/Users/taratorio/erigon/db/kv/temporal/kv_temporal.go:535
github.com/erigontech/erigon/db/kv/temporal.(*Tx).GetAsOf(0x740002e2ea0?, 0x61c0?, {0x14002806bf8?, 0x102ee1fa0?, 0x1?}, 0x0?)
	/Users/taratorio/erigon/db/kv/temporal/kv_temporal.go:539 +0x28
github.com/erigontech/erigon/execution/commitment/commitmentdb.(*HistoryStateReader).Read(0x140000101e0, 0x3, {0x14002806bf8?, 0x0?, 0x74016117438?}, 0x17d784)
	/Users/taratorio/erigon/execution/commitment/commitmentdb/commitment_context.go:101 +0x40
github.com/erigontech/erigon/execution/commitment/backtester.backtestStateReader.Read({{0x10394b4a0?, 0x140000101e0?}, {0x10394b4a0?, 0x140000101f8?}}, 0x1?, {0x14002806bf8?, 0x102ee1fa0?, 0x1014f5ac0?}, 0x740002e2ed0?)
	/Users/taratorio/erigon/execution/commitment/backtester/state_reader.go:52 +0x58
github.com/erigontech/erigon/execution/commitment/commitmentdb.(*TrieContext).readDomain(...)
	/Users/taratorio/erigon/execution/commitment/commitmentdb/commitment_context.go:637
github.com/erigontech/erigon/execution/commitment/commitmentdb.(*TrieContext).Branch(0x740275241f8?, {0x14002806bf8?, 0x0?, 0x0?})
	/Users/taratorio/erigon/execution/commitment/commitmentdb/commitment_context.go:611 +0x40
github.com/erigontech/erigon/execution/commitment.(*HexPatriciaHashed).unfoldBranchNode(0x74027430000, 0x1, 0x2, 0x0)
	/Users/taratorio/erigon/execution/commitment/hex_patricia_hashed.go:1667 +0xb4
github.com/erigontech/erigon/execution/commitment.(*HexPatriciaHashed).unfold(0x74027430000, {0x7401610e000?, 0x14?, 0x18?}, 0x1)
	/Users/taratorio/erigon/execution/commitment/hex_patricia_hashed.go:1768 +0x45c
github.com/erigontech/erigon/execution/commitment.(*HexPatriciaHashed).followAndUpdate(0x74027430000, {0x7401610e000, 0x40, 0x40}, {0x74016110000, 0x14, 0x18}, 0x0)
	/Users/taratorio/erigon/execution/commitment/hex_patricia_hashed.go:2262 +0x1c4
github.com/erigontech/erigon/execution/commitment.(*Updates).ParallelHashSort.func1.1({0x7401610e000?, 0x103191540?, 0x14003380ae8?}, {0x74016110000?, 0x14003380ae8?, 0x1012d1220?}, {0x14003380c00?, 0x0?}, 0x0?)
	/Users/taratorio/erigon/execution/commitment/hex_concurrent_patricia_hashed.go:219 +0x194
github.com/erigontech/erigon/db/etl.(*Collector).Load.func3({0x7401610e000?, 0x0?, 0x0?}, {0x74016110000?, 0x103191540?, 0x0?})
	/Users/taratorio/erigon/db/etl/collector.go:251 +0x38
github.com/erigontech/erigon/db/etl.mergeSortFiles({0x14000b34480, 0x13}, {0x14000e7a200, 0x1, 0x14003380d68?}, 0x74016117dc0, {0x44005682770, 0x0, 0x0, {0x0, ...}, ...}, ...)
	/Users/taratorio/erigon/db/etl/collector.go:344 +0x574
github.com/erigontech/erigon/db/etl.(*Collector).Load(0x44003ba4b80, {0x0, 0x0}, {0x0, 0x0}, 0x4400430a3a0, {0x44005682770, 0x0, 0x0, {0x0, ...}, ...})
	/Users/taratorio/erigon/db/etl/collector.go:253 +0x460
github.com/erigontech/erigon/execution/commitment.(*Updates).ParallelHashSort.func1()
	/Users/taratorio/erigon/execution/commitment/hex_concurrent_patricia_hashed.go:214 +0xec
golang.org/x/sync/errgroup.(*Group).Go.func1()
	/Users/taratorio/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:93 +0x4c
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 1
	/Users/taratorio/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:78 +0x90

@taratorio taratorio requested a review from Giulio2002 as a code owner January 9, 2026 06:46

func NewLatestStateReader(getter kv.TemporalGetter) *LatestStateReader {
return &LatestStateReader{getter: getter}
func NewLatestStateReader(tx kv.TemporalTx, sd sd) *LatestStateReader {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the more common usage is sd sd, tx kv.TemporalTx. This is not too big a deal but it would be good to agree on an order. I don't have an opinion either way, just think consistency would be better.

One other thing just to bear in mind I think that getter kv.TemporalGetter will become redundant when everyting is SD aware. I think I introduced the wrapper kv.TemporalGetter as a tempory measure to svoid spreading sd's too far around the code. Bu if these are everywhere (which I think they should be a ExecutionContexts) I think the wrapper will become redundant at some point.

Although I think I've said this before & it still survives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants