Page MenuHomePhabricator

[chronik] Fix a bug upon tx invalidation
ClosedPublic

Authored by Fabien on Aug 28 2025, 21:23.

Details

Reviewers
tobias_ruck
Group Reviewers
Restricted Project
Commits
rABC465177baa367: [chronik] Fix a bug upon tx invalidation
Summary

When a tx is invalidated due to a conflict, it causes chronik to fail with a double spend error when the invlidation event occurs.
It's time to properly implement the probe_tx function so it doesn't collide with the mempool anymore.

Test Plan
./test/functional/test_runner.py chronik_*

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Fabien requested review of this revision.Aug 28 2025, 21:23
Fabien planned changes to this revision.Aug 28 2025, 21:27

Actually use plugin_outputs_for_tx()

Tail of the build log:

   Compiling itoa v1.0.15
    Checking foldhash v0.1.5
    Checking httpdate v1.0.3
    Checking sync_wrapper v1.0.2
   Compiling ryu v1.0.20
    Checking atomic-waker v1.1.2
    Checking postcard v1.1.2
    Checking hyper v1.6.0
    Checking async-tungstenite v0.29.1
   Compiling chronik-proto v0.1.0 (/work/chronik/chronik-proto)
    Checking karyon_core v0.3.4
    Checking chronik-plugin v0.1.0 (/work/chronik/chronik-plugin)
    Checking tungstenite v0.24.0
    Checking url v2.5.4
    Checking serde_spanned v0.6.9
    Checking toml_datetime v0.6.11
   Compiling pyo3 v0.23.5
    Checking topo_sort v0.4.0
    Checking winnow v0.7.11
    Checking toml_write v0.1.2
    Checking seahash v4.1.0
    Checking mime v0.3.17
    Checking tokio-tungstenite v0.24.0
    Checking hyper-util v0.1.14
    Checking axum-core v0.4.5
   Compiling karyon_jsonrpc_macro v0.3.4
    Checking memoffset v0.9.1
   Compiling chronik-bridge v0.1.0 (/work/chronik/chronik-bridge)
    Checking tower v0.5.2
    Checking serde_urlencoded v0.7.1
    Checking futures-executor v0.3.31
    Checking serde_path_to_error v0.1.17
    Checking matchit v0.7.3
    Checking unicode-segmentation v1.12.0
    Checking base64 v0.22.1
    Checking unindent v0.2.4
    Checking futures v0.3.31
    Checking webpki-roots v1.0.1
    Checking tower-http v0.5.2
    Checking convert_case v0.6.0
    Checking toml_edit v0.22.27
   Compiling librocksdb-sys v0.17.2+9.10.0 (https://github.com/rust-rocksdb/rust-rocksdb.git?rev=c3a42045e9a4de82c2c78ec382625da1afa00c8f#c3a42045)
    Checking axum v0.7.9
   Compiling pyo3-macros v0.23.5
    Checking toml v0.8.23
    Checking chronik-plugin-impl v0.1.0 (/work/chronik/chronik-plugin-impl)
   Compiling aws-lc-rs v1.13.1
   Compiling rustls v0.23.28
    Checking rustls-webpki v0.103.3
    Checking tokio-rustls v0.26.2
    Checking karyon_async_rustls v0.3.4
    Checking karyon_net v0.3.4
    Checking karyon_jsonrpc v0.3.4
    Checking rocksdb v0.23.0 (https://github.com/rust-rocksdb/rust-rocksdb.git?rev=c3a42045e9a4de82c2c78ec382625da1afa00c8f#c3a42045)
    Checking chronik-db v0.1.0 (/work/chronik/chronik-db)
    Checking chronik-indexer v0.1.0 (/work/chronik/chronik-indexer)
    Checking chronik-http v0.1.0 (/work/chronik/chronik-http)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 45s
ninja: build stopped: cannot make progress due to previous errors.
Build build-chronik-plugins failed with exit code 1
tobias_ruck added a subscriber: tobias_ruck.
tobias_ruck added inline comments.
chronik/chronik-db/src/plugins/mem.rs
60 ↗(On Diff #55409)

Any reason not to keep it parallel with tokens?

112 ↗(On Diff #55409)

Possible to use the new function here maybe?

This revision now requires changes to proceed.Aug 28 2025, 21:33
chronik/chronik-db/src/plugins/mem.rs
60 ↗(On Diff #55409)

I was hesitant with this one but if you feel like so I can update

112 ↗(On Diff #55409)

Could be but it will cause an extra loop to add the result to self.plugin_outputs. Since it's simple enough I duplicated to avoid that extra loop

Rename plugins.plugin_outputs_for_tx() to plugins.probe()

Tail of the build log:

   Doc-tests chronik_bridge

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_db

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_http

running 1 test
test chronik/chronik-http/src/protobuf.rs - protobuf::Protobuf (line 29) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.35s

   Doc-tests chronik_indexer

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin_common

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin_impl

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_proto

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_util

running 2 tests
test chronik/chronik-util/src/log.rs - log::log (line 65) ... ignored
test chronik/chronik-util/src/log.rs - log::log_chronik (line 87) ... ignored

test result: ok. 0 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 0.00s

ninja: build stopped: cannot make progress due to previous errors.
Build build-chronik-plugins failed with exit code 1
chronik/chronik-db/src/plugins/mem.rs
60 ↗(On Diff #55409)

I generally tried to keep all the names between the different things consistent (e.g. insert) so I think probe is appropriate. but I may be wrong

112 ↗(On Diff #55409)

that seems like a bad reason, can't you just iterate over the result from plugin_outputs_for_tx and insert it? there doesn't even seem to be a performance impact iiuc, and the end result is much less code

Deduplicate the code as per feedback

Tail of the build log:

   Doc-tests chronik_bridge

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_db

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_http

running 1 test
test chronik/chronik-http/src/protobuf.rs - protobuf::Protobuf (line 29) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.35s

   Doc-tests chronik_indexer

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin_common

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin_impl

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_proto

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_util

running 2 tests
test chronik/chronik-util/src/log.rs - log::log (line 65) ... ignored
test chronik/chronik-util/src/log.rs - log::log_chronik (line 87) ... ignored

test result: ok. 0 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 0.00s

ninja: build stopped: cannot make progress due to previous errors.
Build build-chronik-plugins failed with exit code 1

Tail of the build log:

   Doc-tests chronik_bridge

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_db

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_http

running 1 test
test chronik/chronik-http/src/protobuf.rs - protobuf::Protobuf (line 29) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.36s

   Doc-tests chronik_indexer

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin_common

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_plugin_impl

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_proto

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests chronik_util

running 2 tests
test chronik/chronik-util/src/log.rs - log::log (line 65) ... ignored
test chronik/chronik-util/src/log.rs - log::log_chronik (line 87) ... ignored

test result: ok. 0 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 0.00s

ninja: build stopped: cannot make progress due to previous errors.
Build build-chronik-plugins failed with exit code 1

Rebase to fix the CI build

Im not sure if this works out of the box, but probing in general shouldn’t require mutable access.

chronik/chronik-db/src/mem/mempool.rs
227 ↗(On Diff #55416)

Can we do it immutably? Probing shouldn’t require mutable access

chronik/chronik-db/src/mem/tokens.rs
53 ↗(On Diff #55416)

Same here

chronik/chronik-db/src/plugins/mem.rs
61 ↗(On Diff #55416)

And here.

This revision now requires changes to proceed.Aug 30 2025, 09:18
chronik/chronik-db/src/mem/mempool.rs
227 ↗(On Diff #55416)

So it looks like we can. It was required by a previous iteration but I can't remember why. I will update.

Rebase, use immutable self in probing

This revision is now accepted and ready to land.Sep 2 2025, 06:34
This revision was automatically updated to reflect the committed changes.