Skip to content

Commit bb4954e

Browse files
committed
Fixup: Provide suffix txs in initial template
1 parent 65e8e6b commit bb4954e

4 files changed

Lines changed: 182 additions & 141 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ async-trait = "0.1.81"
1515
bitcoin = "0.32.100"
1616
chrono = "0.4.44"
1717
clap = "4.6.1"
18-
educe = "0.6.0"
18+
educe = { version = "0.6.0", default-features = false }
1919
either = "1.16.0"
2020
futures = "0.3.32"
2121
hashlink = "0.12.0"

lib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ async-trait = { workspace = true }
1212
bitcoin-jsonrpsee = { workspace = true, features = ["tracing"] }
1313
bitcoin = { workspace = true }
1414
chrono = { workspace = true }
15-
educe = { workspace = true }
15+
educe = { workspace = true, features = ["Clone", "Debug", "Default"] }
1616
either = { workspace = true }
1717
futures = { workspace = true }
1818
hashlink = { workspace = true }

lib/cusf_block_producer.rs

Lines changed: 157 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use std::{
2-
collections::HashSet, convert::Infallible, fmt::Debug, future::Future,
3-
};
1+
use std::{convert::Infallible, fmt::Debug, future::Future};
42

5-
use bitcoin::{BlockHash, Transaction, TxOut, Txid};
3+
use bitcoin::{BlockHash, TxOut};
64
use either::Either;
75

86
use crate::cusf_enforcer::{self, CusfEnforcer};
@@ -40,27 +38,128 @@ where
4038
type Output = <typewit::const_marker::Bool<COINBASE_TXN> as CoinbaseTxn>::CoinbaseTxouts;
4139
}
4240

43-
#[derive(Clone, Debug, Default)]
44-
pub struct InitialBlockTemplate<const COINBASE_TXN: bool>
45-
where typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn
41+
pub mod initial_block_template {
42+
use std::collections::HashSet;
43+
44+
use bitcoin::{Transaction, Txid};
45+
46+
use crate::cusf_block_producer::CoinbaseTxn;
47+
48+
pub type TxsItem = (Transaction, bitcoin::Amount);
49+
50+
#[derive(Clone, Debug)]
51+
pub enum SuffixTxsItem {
52+
/// Transaction is already generated
53+
Tx(TxsItem),
54+
/// Reserved, tx will be generated after mempool txs are selected
55+
Reserved { weight: bitcoin::Weight },
56+
}
57+
58+
impl SuffixTxsItem {
59+
pub fn weight(&self) -> bitcoin::Weight {
60+
match self {
61+
Self::Tx((tx, _)) => tx.weight(),
62+
Self::Reserved { weight } => *weight,
63+
}
64+
}
65+
}
66+
67+
#[derive(Clone, Debug, Default)]
68+
pub struct Template<const COINBASE_TXN: bool>
69+
where typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn
70+
{
71+
pub coinbase_txouts: <typewit::const_marker::Bool<COINBASE_TXN> as CoinbaseTxn>::CoinbaseTxouts,
72+
/// Prefix txs, with absolute fee
73+
pub prefix_txs: Vec<TxsItem>,
74+
/// Suffix txs
75+
pub suffix_txs: Vec<SuffixTxsItem>,
76+
/// prefix/suffix txs do not need to be included here
77+
pub exclude_mempool_txs: HashSet<Txid>,
78+
}
79+
}
80+
pub use initial_block_template::Template as InitialBlockTemplate;
81+
82+
pub struct FilledBlockTemplateMut<'a, const COINBASE_TXN: bool>
83+
where typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn
4684
{
47-
pub coinbase_txouts: <typewit::const_marker::Bool<COINBASE_TXN> as CoinbaseTxn>::CoinbaseTxouts,
85+
pub coinbase_txouts: &'a mut <typewit::const_marker::Bool<COINBASE_TXN> as CoinbaseTxn>::CoinbaseTxouts,
4886
/// Prefix txs, with absolute fee
49-
pub prefix_txs: Vec<(Transaction, bitcoin::Amount)>,
50-
/// Suffix txs, with absolute fee
51-
pub suffix_txs: Vec<(Transaction, bitcoin::Amount)>,
52-
/// prefix/suffix txs do not need to be included here
53-
pub exclude_mempool_txs: HashSet<Txid>,
87+
pub prefix_txs: &'a Vec<initial_block_template::TxsItem>,
88+
/// Suffix txs
89+
pub suffix_txs: &'a mut Vec<initial_block_template::TxsItem>,
5490
}
5591

56-
#[derive(Clone, Debug, Default)]
57-
pub struct BlockTemplateSuffix<const COINBASE_TXN: bool>
92+
#[derive(educe::Educe)]
93+
#[educe(Clone, Debug, Default)]
94+
pub struct FilledBlockTemplate<const COINBASE_TXN: bool>
5895
where typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn
5996
{
60-
/// Suffix coinbase txouts
61-
pub coinbase_txouts: <typewit::const_marker::Bool<COINBASE_TXN> as CoinbaseTxn>::CoinbaseTxouts,
62-
/// Suffix txs, with absolute fee
63-
pub txs: Vec<(Transaction, bitcoin::Amount)>,
97+
pub(crate) coinbase_txouts: <typewit::const_marker::Bool<COINBASE_TXN> as CoinbaseTxn>::CoinbaseTxouts,
98+
/// Prefix txs, with absolute fee
99+
pub(crate) prefix_txs: Vec<initial_block_template::TxsItem>,
100+
/// Suffix txs
101+
pub(crate) suffix_txs: Vec<initial_block_template::TxsItem>,
102+
}
103+
104+
impl<const COINBASE_TXN: bool> FilledBlockTemplate<COINBASE_TXN>
105+
where
106+
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
107+
{
108+
pub fn as_mut(&mut self) -> FilledBlockTemplateMut<'_, COINBASE_TXN> {
109+
let Self {
110+
coinbase_txouts,
111+
prefix_txs,
112+
suffix_txs,
113+
} = self;
114+
FilledBlockTemplateMut {
115+
coinbase_txouts,
116+
prefix_txs,
117+
suffix_txs,
118+
}
119+
}
120+
121+
pub fn coinbase_txouts(&mut self) -> &mut <typewit::const_marker::Bool<COINBASE_TXN> as CoinbaseTxn>::CoinbaseTxouts{
122+
&mut self.coinbase_txouts
123+
}
124+
125+
/// Prefix txs, with absolute fee
126+
pub fn prefix_txs(&self) -> &Vec<initial_block_template::TxsItem> {
127+
&self.prefix_txs
128+
}
129+
130+
/// Suffix txs
131+
pub fn suffix_txs(&mut self) -> &mut Vec<initial_block_template::TxsItem> {
132+
&mut self.suffix_txs
133+
}
134+
}
135+
136+
impl<const COINBASE_TXN: bool> From<InitialBlockTemplate<COINBASE_TXN>>
137+
for FilledBlockTemplate<COINBASE_TXN>
138+
where
139+
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
140+
{
141+
fn from(template: InitialBlockTemplate<COINBASE_TXN>) -> Self {
142+
let InitialBlockTemplate {
143+
coinbase_txouts,
144+
prefix_txs,
145+
suffix_txs,
146+
exclude_mempool_txs: _,
147+
} = template;
148+
let suffix_txs = suffix_txs
149+
.into_iter()
150+
.filter_map(|suffix_txs_item| match suffix_txs_item {
151+
initial_block_template::SuffixTxsItem::Tx(tx_item) => {
152+
Some(tx_item)
153+
}
154+
initial_block_template::SuffixTxsItem::Reserved { .. } => None,
155+
})
156+
.collect();
157+
Self {
158+
coinbase_txouts,
159+
prefix_txs,
160+
suffix_txs,
161+
}
162+
}
64163
}
65164

66165
pub trait CusfBlockProducer: CusfEnforcer {
@@ -70,30 +169,21 @@ pub trait CusfBlockProducer: CusfEnforcer {
70169
&self,
71170
parent_block_hash: &BlockHash,
72171
coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
73-
template: InitialBlockTemplate<COINBASE_TXN>,
74-
) -> impl Future<
75-
Output = Result<
76-
InitialBlockTemplate<COINBASE_TXN>,
77-
Self::InitialBlockTemplateError,
78-
>,
79-
> + Send
172+
template: &mut InitialBlockTemplate<COINBASE_TXN>,
173+
) -> impl Future<Output = Result<(), Self::InitialBlockTemplateError>> + Send
80174
where
81175
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn;
82176

83-
type SuffixTxsError: std::error::Error + Send + Sync + 'static;
177+
type FinalizeBlockTemplateError: std::error::Error + Send + Sync + 'static;
84178

85-
/// Add outputs / txs to a block template, after filling with proposed txs
86-
fn block_template_suffix<const COINBASE_TXN: bool>(
179+
/// Finalize coinbase outputs / suffix txs for a block template, after
180+
/// filling with proposed txs
181+
fn finalize_block_template<const COINBASE_TXN: bool>(
87182
&self,
88183
parent_block_hash: &BlockHash,
89184
coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
90-
template: &InitialBlockTemplate<COINBASE_TXN>,
91-
) -> impl Future<
92-
Output = Result<
93-
BlockTemplateSuffix<COINBASE_TXN>,
94-
Self::SuffixTxsError,
95-
>,
96-
> + Send
185+
template: &mut FilledBlockTemplate<COINBASE_TXN>,
186+
) -> impl Future<Output = Result<(), Self::FinalizeBlockTemplateError>> + Send
97187
where
98188
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn;
99189
}
@@ -110,16 +200,12 @@ where
110200
&self,
111201
parent_block_hash: &BlockHash,
112202
coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
113-
mut template: InitialBlockTemplate<COINBASE_TXN>,
114-
) -> Result<
115-
InitialBlockTemplate<COINBASE_TXN>,
116-
Self::InitialBlockTemplateError,
117-
>
203+
template: &mut InitialBlockTemplate<COINBASE_TXN>,
204+
) -> Result<(), Self::InitialBlockTemplateError>
118205
where
119206
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
120207
{
121-
template = self
122-
.0
208+
self.0
123209
.initial_block_template(
124210
parent_block_hash,
125211
coinbase_txn_wit,
@@ -137,64 +223,37 @@ where
137223
.map_err(Either::Right)
138224
}
139225

140-
type SuffixTxsError = Either<C0::SuffixTxsError, C1::SuffixTxsError>;
226+
type FinalizeBlockTemplateError =
227+
Either<C0::FinalizeBlockTemplateError, C1::FinalizeBlockTemplateError>;
141228

142-
async fn block_template_suffix<const COINBASE_TXN: bool>(
229+
async fn finalize_block_template<const COINBASE_TXN: bool>(
143230
&self,
144231
parent_block_hash: &BlockHash,
145232
coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
146-
template: &InitialBlockTemplate<COINBASE_TXN>,
147-
) -> Result<BlockTemplateSuffix<COINBASE_TXN>, Self::SuffixTxsError>
233+
template: &mut FilledBlockTemplate<COINBASE_TXN>,
234+
) -> Result<(), Self::FinalizeBlockTemplateError>
148235
where
149236
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
150237
{
151-
let suffix_left = self
238+
let () = self
152239
.0
153-
.block_template_suffix(
240+
.finalize_block_template(
154241
parent_block_hash,
155242
coinbase_txn_wit,
156243
template,
157244
)
158245
.await
159246
.map_err(Either::Left)?;
160-
let mut template = template.clone();
161-
match coinbase_txn_wit {
162-
typewit::const_marker::BoolWit::True(wit) => {
163-
let wit = wit.map(CoinbaseTxouts);
164-
let coinbase_txouts: &mut Vec<_> =
165-
wit.in_mut().to_right(&mut template.coinbase_txouts);
166-
coinbase_txouts.extend(
167-
wit.in_ref()
168-
.to_right(&suffix_left.coinbase_txouts)
169-
.iter()
170-
.cloned(),
171-
);
172-
}
173-
typewit::const_marker::BoolWit::False(_) => (),
174-
}
175-
template.suffix_txs.extend(suffix_left.txs.iter().cloned());
176-
let suffix_right = self
247+
let () = self
177248
.1
178-
.block_template_suffix(
249+
.finalize_block_template(
179250
parent_block_hash,
180251
coinbase_txn_wit,
181-
&template,
252+
template,
182253
)
183254
.await
184255
.map_err(Either::Right)?;
185-
let mut res = suffix_left;
186-
match coinbase_txn_wit {
187-
typewit::const_marker::BoolWit::True(wit) => {
188-
let wit = wit.map(CoinbaseTxouts);
189-
let coinbase_txouts: &mut Vec<_> =
190-
wit.in_mut().to_right(&mut res.coinbase_txouts);
191-
coinbase_txouts
192-
.extend(wit.to_right(suffix_right.coinbase_txouts));
193-
}
194-
typewit::const_marker::BoolWit::False(_) => (),
195-
}
196-
res.txs.extend(suffix_right.txs);
197-
Ok(res)
256+
Ok(())
198257
}
199258
}
200259

@@ -205,29 +264,26 @@ impl CusfBlockProducer for cusf_enforcer::DefaultEnforcer {
205264
&self,
206265
_parent_block_hash: &BlockHash,
207266
_coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
208-
template: InitialBlockTemplate<COINBASE_TXN>,
209-
) -> Result<
210-
InitialBlockTemplate<COINBASE_TXN>,
211-
Self::InitialBlockTemplateError,
212-
>
267+
_template: &mut InitialBlockTemplate<COINBASE_TXN>,
268+
) -> Result<(), Self::InitialBlockTemplateError>
213269
where
214270
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
215271
{
216-
Ok(template)
272+
Ok(())
217273
}
218274

219-
type SuffixTxsError = Infallible;
275+
type FinalizeBlockTemplateError = Infallible;
220276

221-
async fn block_template_suffix<const COINBASE_TXN: bool>(
277+
async fn finalize_block_template<const COINBASE_TXN: bool>(
222278
&self,
223279
_parent_block_hash: &BlockHash,
224280
_coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
225-
_template: &InitialBlockTemplate<COINBASE_TXN>,
226-
) -> Result<BlockTemplateSuffix<COINBASE_TXN>, Self::SuffixTxsError>
281+
_template: &mut FilledBlockTemplate<COINBASE_TXN>,
282+
) -> Result<(), Self::FinalizeBlockTemplateError>
227283
where
228284
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
229285
{
230-
Ok(BlockTemplateSuffix::default())
286+
Ok(())
231287
}
232288
}
233289

@@ -243,11 +299,8 @@ where
243299
&self,
244300
parent_block_hash: &BlockHash,
245301
coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
246-
template: InitialBlockTemplate<COINBASE_TXN>,
247-
) -> Result<
248-
InitialBlockTemplate<COINBASE_TXN>,
249-
Self::InitialBlockTemplateError,
250-
>
302+
template: &mut InitialBlockTemplate<COINBASE_TXN>,
303+
) -> Result<(), Self::InitialBlockTemplateError>
251304
where
252305
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
253306
{
@@ -271,28 +324,29 @@ where
271324
}
272325
}
273326

274-
type SuffixTxsError = Either<C0::SuffixTxsError, C1::SuffixTxsError>;
327+
type FinalizeBlockTemplateError =
328+
Either<C0::FinalizeBlockTemplateError, C1::FinalizeBlockTemplateError>;
275329

276-
async fn block_template_suffix<const COINBASE_TXN: bool>(
330+
async fn finalize_block_template<const COINBASE_TXN: bool>(
277331
&self,
278332
parent_block_hash: &BlockHash,
279333
coinbase_txn_wit: typewit::const_marker::BoolWit<COINBASE_TXN>,
280-
template: &InitialBlockTemplate<COINBASE_TXN>,
281-
) -> Result<BlockTemplateSuffix<COINBASE_TXN>, Self::SuffixTxsError>
334+
template: &mut FilledBlockTemplate<COINBASE_TXN>,
335+
) -> Result<(), Self::FinalizeBlockTemplateError>
282336
where
283337
typewit::const_marker::Bool<COINBASE_TXN>: CoinbaseTxn,
284338
{
285339
match self {
286340
Self::Left(left) => left
287-
.block_template_suffix(
341+
.finalize_block_template(
288342
parent_block_hash,
289343
coinbase_txn_wit,
290344
template,
291345
)
292346
.await
293347
.map_err(Either::Left),
294348
Self::Right(right) => right
295-
.block_template_suffix(
349+
.finalize_block_template(
296350
parent_block_hash,
297351
coinbase_txn_wit,
298352
template,

0 commit comments

Comments
 (0)