Repository navigation
Give each IBD thread one role. #1233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rearden-grok
wants to merge
8
commits into
master
Choose a base branch
from
ibd/thread-roles
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
2f6e982
Name the IBD header thread ibd-header.
rearden-grok[bot] db97e34
Start rbtc-sh-wb after tip entry.
rearden-grok[bot] cfb4e36
Keep one rbtc-tip-flush thread for IBD Class C barriers.
rearden-grok[bot] f6307ac
Run block-sized pure CPU on rbtc-scripts.
rearden-grok[bot] ff0174f
Start rbtc-sh-wb before catch-up on a durable scripthash head.
rearden-grok[bot] 34cda69
Keep the script worker alive when a run_cpu guest panics.
rearden-grok[bot] 2592225
Move heavy JSON into the script job instead of cloning it on the waiter.
rearden-grok[bot] 34122b4
Panic on script-worker store IO at the syscall and the uring submit.
rearden-grok[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Changed | ||
|
|
||
| - The IBD header thread is named `ibd-header` for the catch-up, then joined. | ||
| - `rbtc-sh-wb` starts when `--sh-index` has the index in Tip. A durable head starts it before catch-up. Direct catch-up starts it only after materialize. It stays down when materialize is cancelled or fails. | ||
| - IBD Class C barriers share one `rbtc-tip-flush` thread for the confirm engine. Tip mode still flushes that barrier on the tip-accept thread. | ||
| - Heavy pure CPU leaves the blocking pool for `rbtc-scripts-*`: v2 encode when `encode_is_cpu_heavy`, compact short ids after the body is in hand, and Electrum or Esplora JSON of at least 4 KiB, including `GET /block-template`. Shorter encodes stay on the caller. Block templates still send `cache-control: no-store`. Block and header decode stay on the blocking pool. | ||
| - A panic inside one of those script-pool jobs does not kill the worker. A dropped JSON encode is an error, not `{}`. A dropped compact-block encode is a peer protocol error, not a header fallback. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| //! JSON replies. Under 4 KiB encodes on the caller. At 4 KiB and above, | ||
| //! encoding runs on `rbtc-scripts-*`. The store join stays where it was. | ||
|
|
||
| use serde_json::Value; | ||
| use std::sync::Arc; | ||
|
|
||
| /// Encoded bodies at or above this leave the caller for `rbtc-scripts-*`. | ||
| pub const JSON_CPU_MIN: usize = 4096; | ||
|
|
||
| /// True when a lower bound of the encoded size reaches [`JSON_CPU_MIN`]. | ||
| /// The walk stops at that bound. | ||
| #[doc(hidden)] | ||
| pub fn json_is_cpu_heavy(v: &Value) -> bool { | ||
| let mut left = JSON_CPU_MIN; | ||
| walk(v, &mut left) | ||
| } | ||
|
|
||
| fn take(left: &mut usize, n: usize) -> bool { | ||
| if n >= *left { | ||
| *left = 0; | ||
| true | ||
| } else { | ||
| *left -= n; | ||
| false | ||
| } | ||
| } | ||
|
|
||
| fn walk(v: &Value, left: &mut usize) -> bool { | ||
| if *left == 0 { | ||
| return true; | ||
| } | ||
| match v { | ||
| Value::Null => take(left, 4), | ||
| Value::Bool(true) => take(left, 4), | ||
| Value::Bool(false) => take(left, 5), | ||
| Value::Number(_) => take(left, 1), | ||
| Value::String(s) => take(left, s.len().saturating_add(2)), | ||
| Value::Array(items) => { | ||
| if take(left, 1) { | ||
| return true; | ||
| } | ||
| for (i, item) in items.iter().enumerate() { | ||
| if i > 0 && take(left, 1) { | ||
| return true; | ||
| } | ||
| if walk(item, left) { | ||
| return true; | ||
| } | ||
| } | ||
| take(left, 1) | ||
| } | ||
| Value::Object(map) => { | ||
| if take(left, 1) { | ||
| return true; | ||
| } | ||
| for (i, (key, item)) in map.iter().enumerate() { | ||
| if i > 0 && take(left, 1) { | ||
| return true; | ||
| } | ||
| if take(left, key.len().saturating_add(3)) || walk(item, left) { | ||
| return true; | ||
| } | ||
| } | ||
| take(left, 1) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Encode `v`. A heavy body hops to `rbtc-scripts-*`. A light body encodes here. | ||
| /// | ||
| /// The `Arc` moves into the script job. Callers that already own the value | ||
| /// do not clone it on the waiting task. `Err` means the worker dropped the | ||
| /// reply. | ||
| #[doc(hidden)] | ||
| pub async fn encode_json_body(v: Arc<Value>) -> Result<Vec<u8>, ()> { | ||
| if !json_is_cpu_heavy(&v) { | ||
| return Ok(serde_json::to_vec(v.as_ref()).unwrap_or_else(|_| b"{}".to_vec())); | ||
| } | ||
| rbitcoin_consensus::script_pool::run_cpu(move || { | ||
| serde_json::to_vec(v.as_ref()).unwrap_or_else(|_| b"{}".to_vec()) | ||
| }) | ||
| .await | ||
| .ok_or(()) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[bug]
run_cpuruns the guest insidespawn_detached, andsteal_or_jobcalls that job with nocatch_unwind. A panic dropsCpuFinish, so the awaiter seesNone, and then the panic leaves therbtc-scripts-*loop.workers()starts those threads once and never replaces a dead one.run_heldalready catches panics. After that,encode_json_bodyturns the dropped reply into a 200 body of{}, andcmpct_from_parts_cpuflattens it toOk(None), so the tip path sends headers. v2 encode already returnsNetError::Protocol("encode task join failed"). On a one-worker pool every laterrun_cpustays pending and script waves stop.Suggestion: Catch the guest panic inside the worker, the same way
run_helddoes, and leave the thread in the loop. KeepNonefor a dropped reply, but do not publish that as HTTP 200{}or as a missing compact body. Compact should use the existing join-failure error.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A guest panic is caught inside run_cpu, the same way run_held catches a script chunk. That worker stays in the pool, and the awaiter still gets None. encode_json_body now returns an error, so Esplora answers 500 instead of a 200 with {}. Compact short ids return the same cmpct relay join failed protocol error as a failed blocking join, so the tip path does not fall through to headers. Fixed in 34cda69.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-checked at 34122b4. A guest panic is still caught inside run_cpu, and the callers still turn a dropped join into an error.