Skip to content
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

Refactor Framing crate #969

Closed

Conversation

jbesraa
Copy link
Contributor

@jbesraa jbesraa commented Jun 12, 2024

relates to #903

This commit aims to refactor the framing-sv2 crate. List of changes:
0. Cleand up header.rs

  1. Removed Frame trait
  2. Changed EitherFrame enum to Frame
  3. Removed unused functions from HandShakeFrame and Sv2Frame
  4. Added documentation where missing
  5. Made sure there is consistency in function naming in Frame, i.e, in
    order to get the header you call Frame::header, for payload
    Frame::payload and so on.
  6. Made sure we dont return mut data from Frame get functions(leave it
    to the caller to decide).
  7. Fixed all the modules in protocols based on the above changes
  8. Fixed all the modules in roles based on the above changes

For 7 & 8 its mainly removing the Frame trait import plus naming fixes
where I renamed StandardEitherFrame to StandardFrame and other name
fixes and also fixing the header and payload calls to align with the
new API.

@jbesraa jbesraa force-pushed the 2024-06-11-framing-sv2-refactor branch 3 times, most recently from f9a97f9 to 6dc8e75 Compare June 13, 2024 05:35
Copy link
Contributor

github-actions bot commented Jun 13, 2024

🐰Bencher

ReportTue, June 18, 2024 at 10:47:34 UTC
ProjectStratum v2 (SRI)
Branch2024-06-11-framing-sv2-refactor
Testbedsv2
Click to view all benchmark results
BenchmarkLatencyLatency Results
nanoseconds (ns) | (Δ%)
Latency Upper Boundary
nanoseconds (ns) | (%)
client_sv2_handle_message_common✅ (view plot)43.86 (-1.55%)45.23 (96.97%)
client_sv2_handle_message_mining✅ (view plot)74.06 (+1.37%)80.25 (92.28%)
client_sv2_mining_message_submit_standard✅ (view plot)14.56 (-0.65%)14.70 (99.04%)
client_sv2_mining_message_submit_standard_serialize✅ (view plot)262.26 (-1.11%)284.90 (92.05%)
client_sv2_mining_message_submit_standard_serialize_deserialize✅ (view plot)597.36 (+0.30%)630.58 (94.73%)
client_sv2_open_channel✅ (view plot)160.97 (-2.71%)171.12 (94.07%)
client_sv2_open_channel_serialize✅ (view plot)280.61 (-0.97%)293.29 (95.68%)
client_sv2_open_channel_serialize_deserialize✅ (view plot)381.25 (+0.34%)423.43 (90.04%)
client_sv2_setup_connection✅ (view plot)160.37 (-2.18%)174.22 (92.05%)
client_sv2_setup_connection_serialize✅ (view plot)497.75 (+4.75%)504.99 (98.57%)
client_sv2_setup_connection_serialize_deserialize✅ (view plot)985.66 (+1.26%)1,039.96 (94.78%)

Bencher - Continuous Benchmarking
View Public Perf Page
Docs | Repo | Chat | Help

Copy link
Contributor

github-actions bot commented Jun 13, 2024

🐰Bencher

ReportTue, June 18, 2024 at 10:47:39 UTC
ProjectStratum v2 (SRI)
Branch2024-06-11-framing-sv2-refactor
Testbedsv1
Click to view all benchmark results
BenchmarkEstimated CyclesEstimated Cycles Results
estimated cycles | (Δ%)
Estimated Cycles Upper Boundary
estimated cycles | (%)
InstructionsInstructions Results
instructions | (Δ%)
Instructions Upper Boundary
instructions | (%)
L1 AccessesL1 Accesses Results
accesses | (Δ%)
L1 Accesses Upper Boundary
accesses | (%)
L2 AccessesL2 Accesses Results
accesses | (Δ%)
L2 Accesses Upper Boundary
accesses | (%)
RAM AccessesRAM Accesses Results
accesses | (Δ%)
RAM Accesses Upper Boundary
accesses | (%)
get_authorize✅ (view plot)8,504.00 (+0.71%)8,719.33 (97.53%)✅ (view plot)3,746.00 (+0.13%)3,849.39 (97.31%)✅ (view plot)5,249.00 (+0.07%)5,393.04 (97.33%)✅ (view plot)7.00 (-10.70%)10.23 (68.44%)✅ (view plot)92.00 (+1.93%)94.23 (97.64%)
get_submit✅ (view plot)95,475.00 (-0.07%)96,101.26 (99.35%)✅ (view plot)59,439.00 (-0.05%)59,758.05 (99.47%)✅ (view plot)85,360.00 (-0.05%)85,807.71 (99.48%)✅ (view plot)49.00 (-9.96%)62.53 (78.37%)✅ (view plot)282.00 (-0.03%)287.36 (98.13%)
get_subscribe✅ (view plot)7,957.00 (-0.22%)8,251.50 (96.43%)✅ (view plot)2,841.00 (+0.35%)2,934.94 (96.80%)✅ (view plot)3,972.00 (+0.41%)4,093.68 (97.03%)✅ (view plot)13.00 (-17.84%)19.84 (65.53%)✅ (view plot)112.00 (-0.50%)116.63 (96.03%)
serialize_authorize✅ (view plot)12,257.00 (+0.37%)12,493.58 (98.11%)✅ (view plot)5,317.00 (+0.09%)5,420.39 (98.09%)✅ (view plot)7,412.00 (+0.05%)7,556.39 (98.09%)✅ (view plot)10.00 (-6.63%)13.19 (75.80%)✅ (view plot)137.00 (+0.94%)140.22 (97.70%)
serialize_deserialize_authorize✅ (view plot)24,554.00 (+0.30%)24,711.21 (99.36%)✅ (view plot)9,898.00 (-0.02%)10,018.76 (98.79%)✅ (view plot)13,959.00 (-0.05%)14,139.73 (98.72%)✅ (view plot)33.00 (-8.78%)41.47 (79.57%)✅ (view plot)298.00 (+0.94%)298.71 (99.76%)
serialize_deserialize_handle_authorize✅ (view plot)30,293.00 (+0.42%)30,381.47 (99.71%)✅ (view plot)12,101.00 (+0.04%)12,204.39 (99.15%)✅ (view plot)17,118.00 (+0.00%)17,270.61 (99.12%)✅ (view plot)59.00 (+0.19%)64.53 (91.43%)✅ (view plot)368.00 (+0.99%)368.74 (99.80%)
serialize_deserialize_handle_submit✅ (view plot)126,372.00 (-0.03%)126,992.49 (99.51%)✅ (view plot)73,224.00 (-0.03%)73,596.46 (99.49%)✅ (view plot)104,947.00 (-0.04%)105,477.98 (99.50%)✅ (view plot)120.00 (-0.37%)130.61 (91.88%)✅ (view plot)595.00 (+0.02%)599.02 (99.33%)
serialize_deserialize_handle_subscribe✅ (view plot)27,457.00 (+0.00%)27,595.94 (99.50%)✅ (view plot)9,643.00 (+0.10%)9,736.94 (99.04%)✅ (view plot)13,642.00 (+0.13%)13,769.16 (99.08%)✅ (view plot)61.00 (-6.80%)73.42 (83.09%)✅ (view plot)386.00 (+0.04%)388.48 (99.36%)
serialize_deserialize_submit✅ (view plot)114,999.00 (-0.06%)115,613.77 (99.47%)✅ (view plot)68,001.00 (-0.07%)68,378.84 (99.45%)✅ (view plot)97,559.00 (-0.08%)98,115.63 (99.43%)✅ (view plot)65.00 (-5.71%)75.18 (86.45%)✅ (view plot)489.00 (+0.16%)492.27 (99.34%)
serialize_deserialize_subscribe✅ (view plot)22,888.00 (+0.05%)23,099.23 (99.09%)✅ (view plot)8,195.00 (+0.10%)8,292.26 (98.83%)✅ (view plot)11,543.00 (+0.10%)11,675.77 (98.86%)✅ (view plot)36.00 (-7.73%)43.97 (81.88%)✅ (view plot)319.00 (+0.13%)321.39 (99.26%)
serialize_submit✅ (view plot)99,792.00 (-0.09%)100,429.36 (99.37%)✅ (view plot)61,483.00 (-0.05%)61,807.12 (99.48%)✅ (view plot)88,207.00 (-0.05%)88,660.85 (99.49%)✅ (view plot)49.00 (-10.83%)62.58 (78.30%)✅ (view plot)324.00 (-0.18%)328.87 (98.52%)
serialize_subscribe✅ (view plot)11,294.00 (-0.25%)11,587.38 (97.47%)✅ (view plot)4,188.00 (+0.24%)4,281.94 (97.81%)✅ (view plot)5,829.00 (+0.26%)5,952.64 (97.92%)✅ (view plot)15.00 (-7.46%)18.82 (79.68%)✅ (view plot)154.00 (-0.70%)159.43 (96.59%)

Bencher - Continuous Benchmarking
View Public Perf Page
Docs | Repo | Chat | Help

Copy link
Contributor

github-actions bot commented Jun 13, 2024

🐰Bencher

ReportTue, June 18, 2024 at 10:47:34 UTC
ProjectStratum v2 (SRI)
Branch969/merge
Testbedsv1
Click to view all benchmark results
BenchmarkLatencyLatency Results
nanoseconds (ns) | (Δ%)
Latency Upper Boundary
nanoseconds (ns) | (%)
client-submit-serialize✅ (view plot)6,523.50 (-4.89%)7,351.97 (88.73%)
client-submit-serialize-deserialize✅ (view plot)7,362.80 (-5.39%)8,312.03 (88.58%)
client-submit-serialize-deserialize-handle/client-submit-serialize-deserialize-handle✅ (view plot)8,022.40 (-3.90%)8,843.52 (90.72%)
client-sv1-authorize-serialize-deserialize-handle/client-sv1-authorize-serialize-deserialize-handle✅ (view plot)895.85 (-0.44%)930.94 (96.23%)
client-sv1-authorize-serialize-deserialize/client-sv1-authorize-serialize-deserialize✅ (view plot)708.50 (+1.37%)721.21 (98.24%)
client-sv1-authorize-serialize/client-sv1-authorize-serialize✅ (view plot)245.40 (-1.16%)255.71 (95.97%)
client-sv1-get-authorize/client-sv1-get-authorize✅ (view plot)157.05 (-0.21%)162.96 (96.37%)
client-sv1-get-submit✅ (view plot)6,183.40 (-6.55%)7,150.26 (86.48%)
client-sv1-get-subscribe/client-sv1-get-subscribe✅ (view plot)281.59 (+0.97%)290.53 (96.92%)
client-sv1-subscribe-serialize-deserialize-handle/client-sv1-subscribe-serialize-deserialize-handle✅ (view plot)782.99 (+3.94%)796.86 (98.26%)
client-sv1-subscribe-serialize-deserialize/client-sv1-subscribe-serialize-deserialize✅ (view plot)621.56 (+0.88%)646.18 (96.19%)
client-sv1-subscribe-serialize/client-sv1-subscribe-serialize✅ (view plot)203.05 (-1.56%)218.73 (92.83%)

Bencher - Continuous Benchmarking
View Public Perf Page
Docs | Repo | Chat | Help

Copy link
Contributor

github-actions bot commented Jun 13, 2024

🐰Bencher

ReportTue, June 18, 2024 at 10:47:35 UTC
ProjectStratum v2 (SRI)
Branch2024-06-11-framing-sv2-refactor
Testbedsv2

🚨 8 ALERTS: Threshold Boundary Limits exceeded!
BenchmarkMeasure (units)ViewValueLower BoundaryUpper Boundary
client_sv2_mining_message_submit_standard_serialize_deserializeInstructions (instructions)🚨 (view plot | view alert)10,910.00 (+3.00%)10,851.38 (100.54%)
client_sv2_mining_message_submit_standard_serialize_deserializeL1 Accesses (accesses)🚨 (view plot | view alert)15,850.00 (+2.86%)15,767.35 (100.52%)
client_sv2_mining_message_submit_standard_serialize_deserializeL2 Accesses (accesses)🚨 (view plot | view alert)91.00 (+8.00%)90.58 (100.47%)
client_sv2_open_channel_serialize_deserializeInstructions (instructions)🚨 (view plot | view alert)8,348.00 (+3.91%)8,289.84 (100.70%)
client_sv2_open_channel_serialize_deserializeL1 Accesses (accesses)🚨 (view plot | view alert)12,120.00 (+3.74%)12,038.74 (100.67%)
client_sv2_open_channel_serialize_deserializeL2 Accesses (accesses)🚨 (view plot | view alert)84.00 (+13.19%)83.88 (100.15%)
client_sv2_setup_connection_serialize_deserializeInstructions (instructions)🚨 (view plot | view alert)15,175.00 (+2.12%)15,116.37 (100.39%)
client_sv2_setup_connection_serialize_deserializeL1 Accesses (accesses)🚨 (view plot | view alert)22,262.00 (+2.02%)22,178.88 (100.37%)

Click to view all benchmark results
BenchmarkEstimated CyclesEstimated Cycles Results
estimated cycles | (Δ%)
Estimated Cycles Upper Boundary
estimated cycles | (%)
InstructionsInstructions Results
instructions | (Δ%)
Instructions Upper Boundary
instructions | (%)
L1 AccessesL1 Accesses Results
accesses | (Δ%)
L1 Accesses Upper Boundary
accesses | (%)
L2 AccessesL2 Accesses Results
accesses | (Δ%)
L2 Accesses Upper Boundary
accesses | (%)
RAM AccessesRAM Accesses Results
accesses | (Δ%)
RAM Accesses Upper Boundary
accesses | (%)
client_sv2_handle_message_common✅ (view plot)2,103.00 (+2.47%)2,129.48 (98.76%)✅ (view plot)473.00 (+0.43%)485.77 (97.37%)✅ (view plot)733.00 (+0.03%)754.78 (97.11%)✅ (view plot)8.00 (+20.79%)10.68 (74.87%)✅ (view plot)38.00 (+3.39%)38.68 (98.24%)
client_sv2_handle_message_mining✅ (view plot)8,293.00 (+0.92%)8,390.49 (98.84%)✅ (view plot)2,143.00 (+0.65%)2,172.18 (98.66%)✅ (view plot)3,163.00 (+0.51%)3,215.32 (98.37%)✅ (view plot)39.00 (+1.88%)43.48 (89.70%)✅ (view plot)141.00 (+1.14%)143.67 (98.14%)
client_sv2_mining_message_submit_standard✅ (view plot)6,344.00 (+0.87%)6,418.61 (98.84%)✅ (view plot)1,756.00 (+0.32%)1,764.16 (99.54%)✅ (view plot)2,554.00 (-0.01%)2,574.96 (99.19%)✅ (view plot)23.00 (+29.19%)23.22 (99.07%)✅ (view plot)105.00 (+0.79%)107.61 (97.57%)
client_sv2_mining_message_submit_standard_serialize✅ (view plot)14,601.00 (-1.17%)15,037.35 (97.10%)✅ (view plot)4,700.00 (+0.12%)4,708.16 (99.83%)✅ (view plot)6,766.00 (+0.15%)6,776.49 (99.85%)✅ (view plot)48.00 (+2.20%)51.61 (93.01%)✅ (view plot)217.00 (-2.43%)230.14 (94.29%)
client_sv2_mining_message_submit_standard_serialize_deserialize✅ (view plot)28,030.00 (+1.69%)28,126.64 (99.66%)🚨 (view plot | view alert)10,910.00 (+3.00%)10,851.38 (100.54%)🚨 (view plot | view alert)15,850.00 (+2.86%)15,767.35 (100.52%)🚨 (view plot | view alert)91.00 (+8.00%)90.58 (100.47%)✅ (view plot)335.00 (-0.08%)345.44 (96.98%)
client_sv2_open_channel✅ (view plot)4,371.00 (-2.40%)4,612.52 (94.76%)✅ (view plot)1,461.00 (+0.05%)1,473.68 (99.14%)✅ (view plot)2,161.00 (+0.34%)2,173.40 (99.43%)✅ (view plot)8.00 (-30.39%)15.49 (51.65%)✅ (view plot)62.00 (-4.30%)68.21 (90.90%)
client_sv2_open_channel_serialize✅ (view plot)13,872.00 (-2.24%)14,479.67 (95.80%)✅ (view plot)5,064.00 (+0.01%)5,076.68 (99.75%)✅ (view plot)7,332.00 (+0.18%)7,340.48 (99.88%)✅ (view plot)34.00 (-8.03%)41.30 (82.32%)✅ (view plot)182.00 (-4.74%)199.36 (91.29%)
client_sv2_open_channel_serialize_deserialize✅ (view plot)23,110.00 (+1.74%)23,226.35 (99.50%)🚨 (view plot | view alert)8,348.00 (+3.91%)8,289.84 (100.70%)🚨 (view plot | view alert)12,120.00 (+3.74%)12,038.74 (100.67%)🚨 (view plot | view alert)84.00 (+13.19%)83.88 (100.15%)✅ (view plot)302.00 (-0.85%)314.35 (96.07%)
client_sv2_setup_connection✅ (view plot)4,719.00 (+0.50%)4,767.14 (98.99%)✅ (view plot)1,502.00 (+0.05%)1,514.68 (99.16%)✅ (view plot)2,274.00 (-0.13%)2,298.44 (98.94%)✅ (view plot)13.00 (+39.61%)13.74 (94.63%)✅ (view plot)68.00 (+0.34%)69.69 (97.58%)
client_sv2_setup_connection_serialize✅ (view plot)16,020.00 (-1.41%)16,484.46 (97.18%)✅ (view plot)5,963.00 (+0.01%)5,975.68 (99.79%)✅ (view plot)8,665.00 (+0.11%)8,677.37 (99.86%)✅ (view plot)43.00 (-3.60%)48.72 (88.25%)✅ (view plot)204.00 (-3.13%)217.28 (93.89%)
client_sv2_setup_connection_serialize_deserialize✅ (view plot)35,982.00 (+1.04%)36,035.88 (99.85%)🚨 (view plot | view alert)15,175.00 (+2.12%)15,116.37 (100.39%)🚨 (view plot | view alert)22,262.00 (+2.02%)22,178.88 (100.37%)✅ (view plot)105.00 (+5.29%)112.05 (93.71%)✅ (view plot)377.00 (-0.73%)384.61 (98.02%)

Bencher - Continuous Benchmarking
View Public Perf Page
Docs | Repo | Chat | Help

@jbesraa jbesraa force-pushed the 2024-06-11-framing-sv2-refactor branch 6 times, most recently from d786508 to dee8b9c Compare June 14, 2024 11:27
@jbesraa
Copy link
Contributor Author

jbesraa commented Jun 14, 2024

Any tips about this failing CI https://github.com/stratum-mining/stratum/actions/runs/9515356472/job/26229428224?pr=969 ? it seems to be failing only on linux, not on mac

@Shourya742
Copy link
Contributor

Hey @jbesraa, could I collaborate on the PR by adding some unit tests? I'm still new to Stratum and believe this would be a great learning opportunity for me. Also, I'm using Linux (Ubuntu distro).

@jbesraa
Copy link
Contributor Author

jbesraa commented Jun 18, 2024

Hey @jbesraa, could I collaborate on the PR by adding some unit tests? I'm still new to Stratum and believe this would be a great learning opportunity for me. Also, I'm using Linux (Ubuntu distro).

Hello @Shourya742

Ofcourse! It would be best if you used this branch as a base and branched out of it and start adding commits. Note that I want to update this branch and split the single commit into smaller detailed commits, so keep an eye on that. It would be also very useful if you wrote down here what you are intending to test so we dont do the same work twice. Happy also to do pair programming here to get things started.

Edit: A great first step would be to take this workflow https://github.com/stratum-mining/stratum/actions/runs/9515356472/workflow?pr=969 and convert it to a shell script so we can run it easily locally. Once we do this, its easier to debug the failing test.

@Shourya742
Copy link
Contributor

Cool @jbesraa
So, this CI issue is deterministic, on my system it is failing as well. I am currently debugging that, will let you know my findings soon. There is some issue with deserialization when we are writing to the stream. And ya breaking it into smaller commits will surely help.

@jbesraa
Copy link
Contributor Author

jbesraa commented Jun 18, 2024

Cool @jbesraa So, this CI issue is deterministic, on my system it is failing as well. I am currently debugging that, will let you know my findings soon. There is some issue with deserialization when we are writing to the stream. And ya breaking it into smaller commits will surely help.

Cool. A note from the work done: If you notice here https://github.com/stratum-mining/stratum/pull/969/files#diff-5cb0e1268eb47c0881cebb757eb5fbb44ce55cdb2d5640581ef3729b74483b88L127 I added this error handling and I think this is where the error first hits, maybe that could be helpful for your debugging.
Sure thing, Ill fix the commit history today.

@@ -142,17 +139,17 @@ impl<'a, T: Serialize + GetSize + Deserialize<'a>, B: IsBuffer + AeadBuffer> Wit
}
self.sv2_buffer.danger_set_start(0);
let src = self.sv2_buffer.get_data_owned();
let frame = Sv2Frame::<T, B::Slice>::from_bytes_unchecked(src);
let frame = Sv2Frame::<T, B::Slice>::from_bytes(src)?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

we can use unchecked here, if you are concerned you can put a check in debug mode

let src = self.noise_buffer.get_data_owned().as_mut().to_vec();

// below is inffalible as noise frame length has been already checked
let frame = HandShakeFrame::from_bytes_unchecked(src.into());
let frame = HandShakeFrame::from_bytes(src.into());
Copy link
Collaborator

Choose a reason for hiding this comment

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

we can use unchecked here, if you are concerned you can put a check in debug mode

@@ -203,7 +200,7 @@ impl<T: Serialize + binary_sv2::GetSize, B: IsBuffer> WithoutNoise<B, T> {
0 => {
self.missing_b = Header::SIZE;
let src = self.buffer.get_data_owned();
let frame = Sv2Frame::<T, B::Slice>::from_bytes_unchecked(src);
let frame = Sv2Frame::<T, B::Slice>::from_bytes(src)?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

we can use unchecked here, if you are concerned you can put a check in debug mode

@jbesraa jbesraa force-pushed the 2024-06-11-framing-sv2-refactor branch 5 times, most recently from f87dc31 to acc8aca Compare June 18, 2024 10:37
1. Removed `NoiseHeader` struct in favor of three constants defined at
the top of the file.
2. Added documentation and changed visibility to `pub(crate)` where
needed.
3. Removed `Header::Default` and `Sv2Frame::Default` impls as they are
unused.
4. Removed `unwrap()`s
@jbesraa jbesraa force-pushed the 2024-06-11-framing-sv2-refactor branch from acc8aca to cdeb873 Compare June 18, 2024 10:43
The `Frame` trait is used solely by a single struct and its only adding
biolerplate to the code without benifits. We could consider re-adding it
in the future if needed.
This commit aims to refactor the `framing-sv2` crate. List of changes:
1. Removed `Frame` trait
2. Changed `EitherFrame` enum to `Frame`
3. Removed unused functions from `HandShakeFrame` and `Sv2Frame`
4. Added documentation where missing
5. Made sure there is consistency in function naming in `Frame`, i.e, in
   order to get the header you call `Frame::header`, for payload
   `Frame::payload` and so on.
6. Made sure we dont return mut data from `Frame` get functions(leave it
   to the caller to decide).
7. Fixed all the modules in `protocols` based on the above changes
8. Fixed all the modules in `roles` based on the above changes

For 7 & 8 its mainly removing the `Frame` trait import plus naming fixes
where I renamed `StandardEitherFrame` to `StandardFrame` and other name
fixes and also fixing the `header` and `payload` calls to align with the
new API.
@jbesraa
Copy link
Contributor Author

jbesraa commented Jun 18, 2024

Breaking this down into smaller PRs, created first one here #976 picking two first commits from here

@Shourya742
Copy link
Contributor

Hey @jbesraa,

I found the CI hiccup—it's due to the extern "C" fn next_frame in /stratum/protocols/v2/sv2-ffi/src/lib.rs. We should swap out the existing payload handling from:

let len = payload.len();
let ptr = payload.as_mut_ptr();
let payload = unsafe { std::slice::from_raw_parts_mut(ptr, len) };

to a safer approach:

let mut payload = payload.to_owned();
let payload = payload.as_mut_slice();

This tweak ditches the unsafe code for something cleaner and should fix the issue. Give it a shot and let’s see if it clears up the CI!

@jbesraa
Copy link
Contributor Author

jbesraa commented Jun 23, 2024

closing in favor of #976 and #982

@jbesraa jbesraa closed this Jun 23, 2024
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