11use crate :: commitments:: Commitments ;
2- use crate :: common:: { Salt , Tag } ;
2+ use crate :: common:: Salt ;
33use crate :: identity:: Identity ;
44use crate :: object_mappings:: ObjectMappings ;
55use crate :: plot:: Plot ;
6+ use crate :: rpc:: {
7+ EncodedBlockWithObjectMapping , FarmerMetadata , ProposedProofOfReplicationResponse , RpcClient ,
8+ SlotInfo , Solution ,
9+ } ;
610use anyhow:: { anyhow, Result } ;
711use futures:: future;
812use futures:: future:: Either ;
9- use jsonrpsee:: types:: traits:: { Client , SubscriptionClient } ;
10- use jsonrpsee:: types:: v2:: params:: JsonRpcParams ;
11- use jsonrpsee:: types:: Subscription ;
12- use jsonrpsee:: ws_client:: { WsClient , WsClientBuilder } ;
1313use log:: { debug, error, info, trace} ;
14- use serde:: { Deserialize , Serialize } ;
1514use std:: path:: PathBuf ;
1615use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
1716use std:: sync:: Arc ;
1817use std:: time:: Instant ;
1918use subspace_archiving:: archiver:: { ArchivedSegment , BlockArchiver , ObjectArchiver } ;
2019use subspace_archiving:: pre_genesis_data;
21- use subspace_core_primitives:: objects:: {
22- BlockObjectMapping , GlobalObject , PieceObject , PieceObjectMapping ,
23- } ;
20+ use subspace_core_primitives:: objects:: { GlobalObject , PieceObject , PieceObjectMapping } ;
2421use subspace_core_primitives:: { crypto, Sha256Hash } ;
2522use subspace_solving:: SubspaceCodec ;
2623
27- type SlotNumber = u64 ;
28-
29- /// Metadata necessary for farmer operation
30- #[ derive( Debug , Deserialize ) ]
31- struct FarmerMetadata {
32- /// Depth `K` after which a block enters the recorded history (a global constant, as opposed
33- /// to the client-dependent transaction confirmation depth `k`).
34- confirmation_depth_k : u32 ,
35- /// The size of data in one piece (in bytes).
36- record_size : u32 ,
37- /// Recorded history is encoded and plotted in segments of this size (in bytes).
38- recorded_history_segment_size : u32 ,
39- /// This constant defines the size (in bytes) of one pre-genesis object.
40- pre_genesis_object_size : u32 ,
41- /// This constant defines the number of a pre-genesis objects that will bootstrap the
42- /// history.
43- pre_genesis_object_count : u32 ,
44- /// This constant defines the seed used for deriving pre-genesis objects that will bootstrap
45- /// the history.
46- pre_genesis_object_seed : Vec < u8 > ,
47- }
48-
49- /// Encoded block with mapping of objects that it contains
50- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
51- struct EncodedBlockWithObjectMapping {
52- /// Encoded block
53- block : Vec < u8 > ,
54- /// Mapping of objects inside of the block
55- object_mapping : BlockObjectMapping ,
56- }
57-
58- // There are more fields in this struct, but we only care about one
59- #[ derive( Debug , Deserialize ) ]
60- struct NewHead {
61- number : String ,
62- }
63-
64- #[ derive( Debug , Serialize ) ]
65- struct Solution {
66- public_key : [ u8 ; 32 ] ,
67- piece_index : u64 ,
68- encoding : Vec < u8 > ,
69- signature : Vec < u8 > ,
70- tag : Tag ,
71- }
72-
73- /// Proposed proof of space consisting of solution and farmer's secret key for block signing
74- #[ derive( Debug , Serialize ) ]
75- struct ProposedProofOfReplicationResponse {
76- /// Slot number
77- slot_number : SlotNumber ,
78- /// Solution (if present) from farmer's plot corresponding to slot number above
79- solution : Option < Solution > ,
80- // Secret key, used for signing blocks on the client node
81- secret_key : Vec < u8 > ,
82- }
83-
84- /// Information about new slot that just arrived
85- #[ derive( Debug , Deserialize ) ]
86- struct SlotInfo {
87- /// Slot number
88- slot_number : SlotNumber ,
89- /// Slot challenge
90- challenge : [ u8 ; 8 ] ,
91- /// Salt
92- salt : Salt ,
93- /// Salt for the next eon
94- next_salt : Option < Salt > ,
95- /// Acceptable solution range
96- solution_range : u64 ,
97- }
98-
9924/// Start farming by using plot in specified path and connecting to WebSocket server at specified
10025/// address.
10126pub ( crate ) async fn farm ( base_directory : PathBuf , ws_server : & str ) -> Result < ( ) > {
102- info ! ( "Connecting to RPC server" ) ;
103- let client = Arc :: new ( WsClientBuilder :: default ( ) . build ( ws_server) . await ?) ;
104-
105- let identity = Identity :: open_or_create ( & base_directory) ?;
106-
107- // TODO: This doesn't account for the fact that node can have a completely different history to
108- // what farmer expects
27+ // TODO: This doesn't account for the fact that node can
28+ // have a completely different history to what farmer expects
10929 info ! ( "Opening plot" ) ;
11030 let plot = Plot :: open_or_create ( & base_directory. clone ( ) . into ( ) ) . await ?;
31+
11132 info ! ( "Opening commitments" ) ;
11233 let commitments = Commitments :: new ( base_directory. join ( "commitments" ) . into ( ) ) . await ?;
34+
11335 info ! ( "Opening object mapping" ) ;
11436 let object_mappings = tokio:: task:: spawn_blocking ( {
11537 let path = base_directory. join ( "object-mappings" ) ;
116-
11738 move || ObjectMappings :: new ( & path)
11839 } )
119- . await
120- . unwrap ( ) ?;
40+ . await ??;
41+
42+ info ! ( "Connecting to RPC server: {}" , ws_server) ;
43+ let client = RpcClient :: new ( ws_server) . await ?;
44+
45+ let identity = Identity :: open_or_create ( & base_directory) ?;
12146
12247 match future:: select (
12348 {
124- let client = Arc :: clone ( & client ) ;
49+ let client = client . clone ( ) ;
12550 let plot = plot. clone ( ) ;
12651 let commitments = commitments. clone ( ) ;
12752 let public_key = identity. public_key ( ) ;
@@ -152,7 +77,7 @@ pub(crate) async fn farm(base_directory: PathBuf, ws_server: &str) -> Result<()>
15277// don't want eventually
15378/// Maintains plot in up to date state plotting new pieces as they are produced on the network.
15479async fn background_plotting < P : AsRef < [ u8 ] > > (
155- client : Arc < WsClient > ,
80+ client : RpcClient ,
15681 plot : Plot ,
15782 commitments : Commitments ,
15883 object_mappings : ObjectMappings ,
@@ -166,9 +91,7 @@ async fn background_plotting<P: AsRef<[u8]>>(
16691 pre_genesis_object_size,
16792 pre_genesis_object_count,
16893 pre_genesis_object_seed,
169- } = client
170- . request ( "subspace_getFarmerMetadata" , JsonRpcParams :: NoParams )
171- . await ?;
94+ } = client. farmer_metadata ( ) . await ?;
17295
17396 // TODO: This assumes fixed size segments, which might not be the case
17497 let merkle_num_leaves = u64:: from ( recorded_history_segment_size / record_size * 2 ) ;
@@ -186,12 +109,7 @@ async fn background_plotting<P: AsRef<[u8]>>(
186109 let last_archived_block_number = last_root_block. last_archived_block ( ) . number ;
187110 info ! ( "Last archived block {}" , last_archived_block_number) ;
188111
189- let maybe_last_archived_block = client
190- . request (
191- "subspace_getBlockByNumber" ,
192- JsonRpcParams :: Array ( vec ! [ serde_json:: to_value( last_archived_block_number) ?] ) ,
193- )
194- . await ?;
112+ let maybe_last_archived_block = client. block_by_number ( last_archived_block_number) . await ?;
195113
196114 match maybe_last_archived_block {
197115 Some ( EncodedBlockWithObjectMapping {
@@ -309,9 +227,9 @@ async fn background_plotting<P: AsRef<[u8]>>(
309227 . map ( |n| n + 1 )
310228 . unwrap_or_default ( ) ;
311229
312- // Erasure coding in archiver and piece encoding are a CPU-intensive operations
230+ // Erasure coding in archiver and piece encoding are CPU-intensive operations.
313231 tokio:: task:: spawn_blocking ( {
314- let client = Arc :: clone ( & client ) ;
232+ let client = client . clone ( ) ;
315233 let weak_plot = weak_plot. clone ( ) ;
316234
317235 #[ allow( clippy:: mut_range_bound) ]
@@ -330,17 +248,10 @@ async fn background_plotting<P: AsRef<[u8]>>(
330248
331249 let mut last_root_block = None ;
332250 for block_to_archive in blocks_to_archive_from..=blocks_to_archive_to {
333- let block_fut = client
334- . request :: < ' _ , ' _ , ' _ , Option < EncodedBlockWithObjectMapping > > (
335- "subspace_getBlockByNumber" ,
336- JsonRpcParams :: Array ( vec ! [
337- serde_json:: to_value( block_to_archive) . unwrap( )
338- ] ) ,
339- ) ;
340251 let EncodedBlockWithObjectMapping {
341252 block,
342253 object_mapping,
343- } = match runtime_handle. block_on ( block_fut ) {
254+ } = match runtime_handle. block_on ( client . block_by_number ( block_to_archive ) ) {
344255 Ok ( Some ( block) ) => block,
345256 Ok ( None ) => {
346257 error ! (
@@ -427,22 +338,16 @@ async fn background_plotting<P: AsRef<[u8]>>(
427338 }
428339 } ) ;
429340
430- info ! ( "Subscribing to new heads notifications" ) ;
431-
432- let mut subscription: Subscription < NewHead > = client
433- . subscribe (
434- "chain_subscribeNewHead" ,
435- JsonRpcParams :: NoParams ,
436- "chain_unsubscribeNewHead" ,
437- )
438- . await ?;
341+ info ! ( "Subscribing to new heads" ) ;
342+ let mut new_head = client. subscribe_new_head ( ) . await ?;
439343
440344 let block_to_archive = Arc :: new ( AtomicU32 :: default ( ) ) ;
345+
441346 // Listen for new blocks produced on the network
442- while let Some ( new_head ) = subscription . next ( ) . await ? {
347+ while let Some ( head ) = new_head . next ( ) . await ? {
443348 // Numbers are in the format `0xabcd`, so strip `0x` prefix and interpret the rest as an
444349 // integer in hex
445- let block_number = u32:: from_str_radix ( & new_head . number [ 2 ..] , 16 ) . unwrap ( ) ;
350+ let block_number = u32:: from_str_radix ( & head . number [ 2 ..] , 16 ) . unwrap ( ) ;
446351 debug ! ( "Last block number: {:#?}" , block_number) ;
447352
448353 if let Some ( block) = block_number. checked_sub ( confirmation_depth_k) {
@@ -479,25 +384,19 @@ fn create_global_object_mapping(
479384}
480385
481386async fn subscribe_to_slot_info (
482- client : & WsClient ,
387+ client : & RpcClient ,
483388 plot : & Plot ,
484389 commitments : & Commitments ,
485390 identity : & Identity ,
486391) -> Result < ( ) > {
487392 let farmer_public_key_hash = crypto:: sha256_hash ( & identity. public_key ( ) ) ;
488393
489- info ! ( "Subscribing to slot info notifications" ) ;
490- let mut subscription: Subscription < SlotInfo > = client
491- . subscribe (
492- "subspace_subscribeSlotInfo" ,
493- JsonRpcParams :: NoParams ,
494- "subspace_unsubscribeSlotInfo" ,
495- )
496- . await ?;
394+ info ! ( "Subscribing to slot info" ) ;
395+ let mut new_slots = client. subscribe_slot_info ( ) . await ?;
497396
498397 let mut salts = Salts :: default ( ) ;
499398
500- while let Some ( slot_info) = subscription . next ( ) . await ? {
399+ while let Some ( slot_info) = new_slots . next ( ) . await ? {
501400 debug ! ( "New slot: {:?}" , slot_info) ;
502401
503402 update_commitments ( plot, commitments, & mut salts, & slot_info) ;
@@ -511,14 +410,13 @@ async fn subscribe_to_slot_info(
511410 {
512411 Some ( ( tag, piece_index) ) => {
513412 let encoding = plot. read ( piece_index) . await ?;
514- let solution = Solution {
515- public_key : identity. public_key ( ) . to_bytes ( ) ,
413+ let solution = Solution :: new (
414+ identity. public_key ( ) . to_bytes ( ) ,
516415 piece_index,
517- encoding : encoding . to_vec ( ) ,
518- signature : identity. sign ( & tag) . to_bytes ( ) . to_vec ( ) ,
416+ encoding. to_vec ( ) ,
417+ identity. sign ( & tag) . to_bytes ( ) . to_vec ( ) ,
519418 tag,
520- } ;
521-
419+ ) ;
522420 debug ! ( "Solution found" ) ;
523421 trace ! ( "Solution found: {:?}" , solution) ;
524422
@@ -531,16 +429,11 @@ async fn subscribe_to_slot_info(
531429 } ;
532430
533431 client
534- . request (
535- "subspace_proposeProofOfReplication" ,
536- JsonRpcParams :: Array ( vec ! [ serde_json:: to_value(
537- & ProposedProofOfReplicationResponse {
538- slot_number: slot_info. slot_number,
539- solution,
540- secret_key: identity. secret_key( ) . to_bytes( ) . into( ) ,
541- } ,
542- ) ?] ) ,
543- )
432+ . propose_proof_of_replication ( ProposedProofOfReplicationResponse {
433+ slot_number : slot_info. slot_number ,
434+ solution,
435+ secret_key : identity. secret_key ( ) . to_bytes ( ) . into ( ) ,
436+ } )
544437 . await ?;
545438 }
546439
0 commit comments