1
+ use bytes:: Bytes ;
2
+ use futures:: future:: BoxFuture ;
3
+ use futures:: FutureExt ;
1
4
use std:: {
2
5
future:: { ready, Ready } ,
3
6
task:: { Context , Poll } ,
4
7
} ;
5
-
6
- use futures:: future:: BoxFuture ;
7
- use futures:: FutureExt ;
8
8
use tower:: { Service , ServiceExt } ;
9
9
10
10
use cuprate_blockchain:: service:: BlockchainReadHandle ;
@@ -15,7 +15,11 @@ use cuprate_helper::map::{combine_low_high_bits_to_u128, split_u128_into_low_hig
15
15
use cuprate_p2p:: constants:: MAX_BLOCK_BATCH_LEN ;
16
16
use cuprate_p2p_core:: { client:: PeerInformation , NetworkZone , ProtocolRequest , ProtocolResponse } ;
17
17
use cuprate_types:: blockchain:: { BlockchainReadRequest , BlockchainResponse } ;
18
- use cuprate_wire:: protocol:: { ChainRequest , ChainResponse , GetObjectsRequest , GetObjectsResponse } ;
18
+ use cuprate_types:: { BlockCompleteEntry , MissingTxsInBlock , TransactionBlobs } ;
19
+ use cuprate_wire:: protocol:: {
20
+ ChainRequest , ChainResponse , FluffyMissingTransactionsRequest , GetObjectsRequest ,
21
+ GetObjectsResponse , NewFluffyBlock ,
22
+ } ;
19
23
20
24
#[ derive( Clone ) ]
21
25
pub struct P2pProtocolRequestHandlerMaker {
@@ -63,12 +67,20 @@ impl<Z: NetworkZone> Service<ProtocolRequest> for P2pProtocolRequestHandler<Z> {
63
67
ProtocolRequest :: GetObjects ( r) => {
64
68
get_objects ( r, self . blockchain_read_handle . clone ( ) ) . boxed ( )
65
69
}
66
- ProtocolRequest :: GetChain ( _) => todo ! ( ) ,
67
- ProtocolRequest :: FluffyMissingTxs ( _) => todo ! ( ) ,
68
- ProtocolRequest :: GetTxPoolCompliment ( _) => todo ! ( ) ,
69
- ProtocolRequest :: NewBlock ( _) => todo ! ( ) ,
70
+ ProtocolRequest :: GetChain ( r) => {
71
+ get_chain ( r, self . blockchain_read_handle . clone ( ) ) . boxed ( )
72
+ }
73
+ ProtocolRequest :: FluffyMissingTxs ( r) => {
74
+ fluffy_missing_txs ( r, self . blockchain_read_handle . clone ( ) ) . boxed ( )
75
+ }
76
+ ProtocolRequest :: NewBlock ( _) => ready ( Err ( anyhow:: anyhow!(
77
+ "Peer sent a full block when we support fluffy blocks"
78
+ ) ) )
79
+ . boxed ( ) ,
70
80
ProtocolRequest :: NewFluffyBlock ( _) => todo ! ( ) ,
71
- ProtocolRequest :: NewTransactions ( _) => todo ! ( ) ,
81
+ ProtocolRequest :: GetTxPoolCompliment ( _) | ProtocolRequest :: NewTransactions ( _) => {
82
+ ready ( Ok ( ProtocolResponse :: NA ) ) . boxed ( )
83
+ } // TODO: tx-pool
72
84
}
73
85
}
74
86
}
@@ -138,6 +150,10 @@ async fn get_chain(
138
150
panic ! ( "blockchain returned wrong response!" ) ;
139
151
} ;
140
152
153
+ if start_height == 0 {
154
+ anyhow:: bail!( "The peers chain has a different genesis block than ours." ) ;
155
+ }
156
+
141
157
let ( cumulative_difficulty_low64, cumulative_difficulty_top64) =
142
158
split_u128_into_low_high_bits ( cumulative_difficulty) ;
143
159
@@ -147,7 +163,7 @@ async fn get_chain(
147
163
cumulative_difficulty_low64,
148
164
cumulative_difficulty_top64,
149
165
m_block_ids : ByteArrayVec :: from ( block_ids) ,
150
- first_block : Default :: default ( ) ,
166
+ first_block : first_block_blob . map_or ( Bytes :: new ( ) , Bytes :: from ) ,
151
167
// only needed when
152
168
m_block_weights : if want_pruned_data {
153
169
block_weights. into_iter ( ) . map ( usize_to_u64) . collect ( )
@@ -156,3 +172,43 @@ async fn get_chain(
156
172
} ,
157
173
} ) )
158
174
}
175
+
176
+ /// [`ProtocolRequest::FluffyMissingTxs`]
177
+ async fn fluffy_missing_txs (
178
+ mut request : FluffyMissingTransactionsRequest ,
179
+ mut blockchain_read_handle : BlockchainReadHandle ,
180
+ ) -> anyhow:: Result < ProtocolResponse > {
181
+ let tx_indexes = std:: mem:: take ( & mut request. missing_tx_indices ) ;
182
+ let block_hash: [ u8 ; 32 ] = * request. block_hash ;
183
+ let current_blockchain_height = request. current_blockchain_height ;
184
+
185
+ // de-allocate the backing `Bytes`.
186
+ drop ( request) ;
187
+
188
+ let BlockchainResponse :: MissingTxsInBlock ( res) = blockchain_read_handle
189
+ . ready ( )
190
+ . await ?
191
+ . call ( BlockchainReadRequest :: MissingTxsInBlock {
192
+ block_hash,
193
+ tx_indexes,
194
+ } )
195
+ . await ?
196
+ else {
197
+ panic ! ( "blockchain returned wrong response!" ) ;
198
+ } ;
199
+
200
+ let Some ( MissingTxsInBlock { block, txs } ) = res else {
201
+ anyhow:: bail!( "The peer requested txs out of range." ) ;
202
+ } ;
203
+
204
+ Ok ( ProtocolResponse :: NewFluffyBlock ( NewFluffyBlock {
205
+ b : BlockCompleteEntry {
206
+ block : Bytes :: from ( block) ,
207
+ txs : TransactionBlobs :: Normal ( txs. into_iter ( ) . map ( Bytes :: from) . collect ( ) ) ,
208
+ pruned : false ,
209
+ // only needed for pruned blocks.
210
+ block_weight : 0 ,
211
+ } ,
212
+ current_blockchain_height,
213
+ } ) )
214
+ }
0 commit comments