Skip to content

Commit 23f38b1

Browse files
committed
introduce generic jobs to server channels
1 parent 802c84c commit 23f38b1

File tree

6 files changed

+563
-315
lines changed

6 files changed

+563
-315
lines changed

sv2/channels-sv2/src/server/extended.rs

Lines changed: 86 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ use crate::{
4444
merkle_root::merkle_root_from_path,
4545
server::{
4646
error::ExtendedChannelError,
47-
jobs::{extended::ExtendedJob, factory::JobFactory, job_store::JobStore, JobOrigin},
47+
jobs::{
48+
extended::ExtendedJob, factory::JobFactoryExtended, job_store::JobStore, JobOrigin,
49+
},
4850
share_accounting::{ShareAccounting, ShareValidationError, ShareValidationResult},
4951
},
5052
target::{bytes_to_hex, hash_rate_to_target, u256_to_block_hash},
@@ -83,9 +85,11 @@ use tracing::debug;
8385
/// - the channel's job factory
8486
/// - the channel's chain tip
8587
#[derive(Debug)]
86-
pub struct ExtendedChannel<'a, J>
88+
pub struct ExtendedChannel<'a, J, E, F>
8789
where
88-
J: JobStore<ExtendedJob<'a>>,
90+
E: ExtendedJob<'a>,
91+
F: JobFactoryExtended<'a, E>,
92+
J: JobStore<E>,
8993
{
9094
channel_id: u32,
9195
user_identity: String,
@@ -95,16 +99,18 @@ where
9599
target: Target, // todo: try to use Target from rust-bitcoin
96100
nominal_hashrate: f32,
97101
job_store: J,
98-
job_factory: JobFactory,
102+
job_factory: F,
99103
share_accounting: ShareAccounting,
100104
expected_share_per_minute: f32,
101105
chain_tip: Option<ChainTip>,
102-
phantom: PhantomData<&'a ()>,
106+
phantom: PhantomData<(E, &'a ())>,
103107
}
104108

105-
impl<'a, J> ExtendedChannel<'a, J>
109+
impl<'a, J, E, F> ExtendedChannel<'a, J, E, F>
106110
where
107-
J: JobStore<ExtendedJob<'a>>,
111+
E: ExtendedJob<'a>,
112+
F: JobFactoryExtended<'a, E>,
113+
J: JobStore<E>,
108114
{
109115
/// Constructor of `ExtendedChannel` for a Sv2 Pool Server.
110116
/// Not meant for usage on a Sv2 Job Declaration Client.
@@ -243,7 +249,7 @@ where
243249
target,
244250
nominal_hashrate,
245251
job_store,
246-
job_factory: JobFactory::new(version_rolling_allowed, pool_tag, miner_tag),
252+
job_factory: F::new_factory_extended(version_rolling_allowed, pool_tag, miner_tag),
247253
share_accounting: ShareAccounting::new(share_batch_size),
248254
expected_share_per_minute,
249255
chain_tip: None,
@@ -408,19 +414,19 @@ where
408414
}
409415

410416
/// Returns an owned copy of the currently active job, if any.
411-
pub fn get_active_job(&self) -> Option<ExtendedJob<'a>> {
417+
pub fn get_active_job(&self) -> Option<E> {
412418
// cloning happens inside the job store
413419
self.job_store.get_active_job()
414420
}
415421

416422
/// Returns an owned copy of a future job from its job ID, if any.
417-
pub fn get_future_job(&self, job_id: u32) -> Option<ExtendedJob<'a>> {
423+
pub fn get_future_job(&self, job_id: u32) -> Option<E> {
418424
// cloning happens inside the job store
419425
self.job_store.get_future_job(job_id)
420426
}
421427

422428
/// Returns an owned copy of a past job from its job ID, if any.
423-
pub fn get_past_job(&self, job_id: u32) -> Option<ExtendedJob<'a>> {
429+
pub fn get_past_job(&self, job_id: u32) -> Option<E> {
424430
// cloning happens inside the job store
425431
self.job_store.get_past_job(job_id)
426432
}
@@ -738,7 +744,12 @@ mod tests {
738744
server::{
739745
error::ExtendedChannelError,
740746
extended::ExtendedChannel,
741-
jobs::job_store::{DefaultJobStore, JobStore},
747+
jobs::{
748+
extended::{DefaultExtendedJob, ExtendedJob},
749+
factory::DefaultJobFactory,
750+
job_store::{DefaultJobStore, JobStore},
751+
Job,
752+
},
742753
share_accounting::{ShareValidationError, ShareValidationResult},
743754
},
744755
};
@@ -768,9 +779,14 @@ mod tests {
768779
let version_rolling_allowed = true;
769780
let rollable_extranonce_size = 4u16;
770781
let share_batch_size = 100;
771-
let job_store = DefaultJobStore::new();
772-
773-
let mut channel = ExtendedChannel::new(
782+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
783+
784+
let mut channel: ExtendedChannel<
785+
'_,
786+
DefaultJobStore<DefaultExtendedJob>,
787+
DefaultExtendedJob,
788+
DefaultJobFactory,
789+
> = ExtendedChannel::new(
774790
channel_id,
775791
user_identity,
776792
extranonce_prefix,
@@ -914,9 +930,14 @@ mod tests {
914930
let version_rolling_allowed = true;
915931
let rollable_extranonce_size = 4u16;
916932
let share_batch_size = 100;
917-
let job_store = DefaultJobStore::new();
918-
919-
let mut channel = ExtendedChannel::new(
933+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
934+
935+
let mut channel: ExtendedChannel<
936+
'_,
937+
DefaultJobStore<DefaultExtendedJob>,
938+
DefaultExtendedJob,
939+
DefaultJobFactory,
940+
> = ExtendedChannel::new(
920941
channel_id,
921942
user_identity,
922943
extranonce_prefix,
@@ -1034,9 +1055,14 @@ mod tests {
10341055
let version_rolling_allowed = true;
10351056
let rollable_extranonce_size = 4u16;
10361057
let share_batch_size = 100;
1037-
let job_store = DefaultJobStore::new();
1038-
1039-
let mut channel = ExtendedChannel::new(
1058+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
1059+
1060+
let mut channel: ExtendedChannel<
1061+
'_,
1062+
DefaultJobStore<DefaultExtendedJob>,
1063+
DefaultExtendedJob,
1064+
DefaultJobFactory,
1065+
> = ExtendedChannel::new(
10401066
channel_id,
10411067
user_identity,
10421068
extranonce_prefix,
@@ -1112,9 +1138,14 @@ mod tests {
11121138
let version_rolling_allowed = true;
11131139
let rollable_extranonce_size = 8u16;
11141140
let share_batch_size = 100;
1115-
let job_store = DefaultJobStore::new();
1116-
1117-
let mut channel = ExtendedChannel::new(
1141+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
1142+
1143+
let mut channel: ExtendedChannel<
1144+
'_,
1145+
DefaultJobStore<DefaultExtendedJob>,
1146+
DefaultExtendedJob,
1147+
DefaultJobFactory,
1148+
> = ExtendedChannel::new(
11181149
channel_id,
11191150
user_identity,
11201151
extranonce_prefix,
@@ -1224,9 +1255,14 @@ mod tests {
12241255
let version_rolling_allowed = true;
12251256
let rollable_extranonce_size = 8u16;
12261257
let share_batch_size = 100;
1227-
let job_store = DefaultJobStore::new();
1228-
1229-
let mut channel = ExtendedChannel::new(
1258+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
1259+
1260+
let mut channel: ExtendedChannel<
1261+
'_,
1262+
DefaultJobStore<DefaultExtendedJob>,
1263+
DefaultExtendedJob,
1264+
DefaultJobFactory,
1265+
> = ExtendedChannel::new(
12301266
channel_id,
12311267
user_identity,
12321268
extranonce_prefix,
@@ -1336,9 +1372,14 @@ mod tests {
13361372
let version_rolling_allowed = true;
13371373
let rollable_extranonce_size = 8u16;
13381374
let share_batch_size = 100;
1339-
let job_store = DefaultJobStore::new();
1340-
1341-
let mut channel = ExtendedChannel::new(
1375+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
1376+
1377+
let mut channel: ExtendedChannel<
1378+
'_,
1379+
DefaultJobStore<DefaultExtendedJob>,
1380+
DefaultExtendedJob,
1381+
DefaultJobFactory,
1382+
> = ExtendedChannel::new(
13421383
channel_id,
13431384
user_identity,
13441385
extranonce_prefix,
@@ -1459,13 +1500,18 @@ mod tests {
14591500
let version_rolling_allowed = true;
14601501
let rollable_extranonce_size = 4u16;
14611502
let share_batch_size = 100;
1462-
let job_store = DefaultJobStore::new();
1503+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
14631504

14641505
// this is the most permissive possible max_target
14651506
let max_target = Target::from_le_bytes([0xff; 32]);
14661507

14671508
// Create a channel with initial hashrate
1468-
let mut channel = ExtendedChannel::new(
1509+
let mut channel: ExtendedChannel<
1510+
'_,
1511+
DefaultJobStore<DefaultExtendedJob>,
1512+
DefaultExtendedJob,
1513+
DefaultJobFactory,
1514+
> = ExtendedChannel::new(
14691515
channel_id,
14701516
user_identity,
14711517
extranonce_prefix,
@@ -1550,9 +1596,14 @@ mod tests {
15501596
let version_rolling_allowed = true;
15511597
let rollable_extranonce_size = 4u16;
15521598
let share_batch_size = 100;
1553-
let job_store = DefaultJobStore::new();
1554-
1555-
let mut channel = ExtendedChannel::new(
1599+
let job_store: DefaultJobStore<DefaultExtendedJob> = DefaultJobStore::new();
1600+
1601+
let mut channel: ExtendedChannel<
1602+
'_,
1603+
DefaultJobStore<DefaultExtendedJob>,
1604+
DefaultExtendedJob,
1605+
DefaultJobFactory,
1606+
> = ExtendedChannel::new(
15561607
channel_id,
15571608
user_identity,
15581609
extranonce_prefix.clone(),

sv2/channels-sv2/src/server/group.rs

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::{
3535
chain_tip::ChainTip,
3636
server::{
3737
error::GroupChannelError,
38-
jobs::{extended::ExtendedJob, factory::JobFactory, job_store::JobStore},
38+
jobs::{extended::ExtendedJob, factory::JobFactoryExtended, job_store::JobStore},
3939
},
4040
};
4141
use bitcoin::transaction::TxOut;
@@ -58,22 +58,26 @@ use template_distribution_sv2::{NewTemplate, SetNewPrevHash as SetNewPrevHashTdp
5858
/// - the group channel's stale jobs
5959
/// - the group channel's share validation state
6060
#[derive(Debug)]
61-
pub struct GroupChannel<'a, J>
61+
pub struct GroupChannel<'a, J, E, F>
6262
where
63-
J: JobStore<ExtendedJob<'a>>,
63+
J: JobStore<E>,
64+
E: ExtendedJob<'a>,
65+
F: JobFactoryExtended<'a, E>,
6466
{
6567
group_channel_id: u32,
6668
standard_channel_ids: HashSet<u32>,
67-
job_factory: JobFactory,
69+
job_factory: F,
6870
job_store: J,
6971
chain_tip: Option<ChainTip>,
7072
full_extranonce_size: usize,
71-
phantom: PhantomData<&'a ()>,
73+
phantom: PhantomData<(E, &'a ())>,
7274
}
7375

74-
impl<'a, J> GroupChannel<'a, J>
76+
impl<'a, J, E, F> GroupChannel<'a, J, E, F>
7577
where
76-
J: JobStore<ExtendedJob<'a>>,
78+
J: JobStore<E>,
79+
E: ExtendedJob<'a>,
80+
F: JobFactoryExtended<'a, E>,
7781
{
7882
/// Constructor of `GroupChannel` for a Sv2 Pool Server.
7983
/// Not meant for usage on a Sv2 Job Declaration Client.
@@ -149,7 +153,7 @@ where
149153
Ok(Self {
150154
group_channel_id,
151155
standard_channel_ids: HashSet::new(),
152-
job_factory: JobFactory::new(true, pool_tag, miner_tag),
156+
job_factory: F::new_factory_extended(true, pool_tag, miner_tag),
153157
job_store,
154158
chain_tip: None,
155159
full_extranonce_size,
@@ -193,7 +197,7 @@ where
193197
}
194198

195199
/// Returns an owned copy of the currently active job, if any.
196-
pub fn get_active_job(&self) -> Option<ExtendedJob<'a>> {
200+
pub fn get_active_job(&self) -> Option<E> {
197201
// cloning happens inside the job store
198202
self.job_store.get_active_job()
199203
}
@@ -205,7 +209,7 @@ where
205209
}
206210

207211
/// Returns an owned copy of a future job from its job ID, if any.
208-
pub fn get_future_job(&self, job_id: u32) -> Option<ExtendedJob<'a>> {
212+
pub fn get_future_job(&self, job_id: u32) -> Option<E> {
209213
// cloning happens inside the job store
210214
self.job_store.get_future_job(job_id)
211215
}
@@ -300,7 +304,12 @@ mod tests {
300304
chain_tip::ChainTip,
301305
server::{
302306
group::GroupChannel,
303-
jobs::job_store::{DefaultJobStore, JobStore},
307+
jobs::{
308+
extended::{DefaultExtendedJob, ExtendedJob},
309+
factory::DefaultJobFactory,
310+
job_store::{DefaultJobStore, JobStore},
311+
Job,
312+
},
304313
},
305314
};
306315
use binary_sv2::Sv2Option;
@@ -317,9 +326,13 @@ mod tests {
317326
// the messages on this test were collected from a sane message flow
318327
// we use them as test vectors to assert correct behavior of job creation
319328
let group_channel_id = 1;
320-
let job_store = DefaultJobStore::new();
329+
let job_store: DefaultJobStore<DefaultExtendedJob<'_>> = DefaultJobStore::new();
321330
let full_extranonce_size = 32;
322-
let mut group_channel = GroupChannel::new(
331+
let mut group_channel = GroupChannel::<
332+
DefaultJobStore<DefaultExtendedJob<'_>>,
333+
DefaultExtendedJob<'_>,
334+
DefaultJobFactory,
335+
>::new(
323336
group_channel_id,
324337
job_store,
325338
full_extranonce_size,
@@ -449,7 +462,11 @@ mod tests {
449462

450463
let job_store = DefaultJobStore::new();
451464
let full_extranonce_size = 32;
452-
let mut group_channel = GroupChannel::new(
465+
let mut group_channel = GroupChannel::<
466+
DefaultJobStore<DefaultExtendedJob<'_>>,
467+
DefaultExtendedJob<'_>,
468+
DefaultJobFactory,
469+
>::new(
453470
group_channel_id,
454471
job_store,
455472
full_extranonce_size,
@@ -507,7 +524,7 @@ mod tests {
507524
.on_new_template(template.clone(), coinbase_reward_outputs)
508525
.unwrap();
509526

510-
let active_job = group_channel.get_active_job().unwrap();
527+
let active_job: DefaultExtendedJob<'_> = group_channel.get_active_job().unwrap();
511528

512529
// we know that the provided template + coinbase_reward_outputs should generate this
513530
// non-future job
@@ -545,9 +562,13 @@ mod tests {
545562
// we use them as test vectors to assert correct behavior of job creation
546563
let group_channel_id = 1;
547564

548-
let job_store = DefaultJobStore::new();
565+
let job_store: DefaultJobStore<DefaultExtendedJob<'_>> = DefaultJobStore::new();
549566
let full_extranonce_size = 32;
550-
let mut group_channel = GroupChannel::new(
567+
let mut group_channel = GroupChannel::<
568+
DefaultJobStore<DefaultExtendedJob<'_>>,
569+
DefaultExtendedJob<'_>,
570+
DefaultJobFactory,
571+
>::new(
551572
group_channel_id,
552573
job_store,
553574
full_extranonce_size,

0 commit comments

Comments
 (0)