3
3
use alloy_eips:: eip1898:: BlockNumberOrTag ;
4
4
use alloy_network:: AnyNetwork ;
5
5
use alloy_primitives:: { Bytes , B256 } ;
6
- use alloy_provider:: RootProvider ;
6
+ use alloy_provider:: { ReqwestProvider , RootProvider } ;
7
7
use alloy_rpc_client:: RpcClient ;
8
8
use alloy_rpc_types_engine:: {
9
9
ExecutionPayloadV3 , ForkchoiceState , ForkchoiceUpdated , JwtSecret , PayloadId , PayloadStatus ,
@@ -17,12 +17,16 @@ use alloy_transport_http::{
17
17
} ;
18
18
use async_trait:: async_trait;
19
19
use http_body_util:: Full ;
20
- use op_alloy_protocol:: L2BlockInfo ;
20
+ use op_alloy_genesis:: RollupConfig ;
21
+ use op_alloy_protocol:: { BatchValidationProvider , L2BlockInfo } ;
21
22
use op_alloy_provider:: ext:: engine:: OpEngineApi ;
22
23
use op_alloy_rpc_types_engine:: { OpExecutionPayloadEnvelopeV3 , OpPayloadAttributes } ;
24
+ use std:: sync:: Arc ;
23
25
use tower:: ServiceBuilder ;
24
26
use url:: Url ;
25
27
28
+ use hilo_providers_alloy:: AlloyL2ChainProvider ;
29
+
26
30
use crate :: { Engine , EngineApiError } ;
27
31
28
32
/// A Hyper HTTP client with a JWT authentication layer.
@@ -31,24 +35,28 @@ type HyperAuthClient<B = Full<Bytes>> = HyperClient<B, AuthService<Client<HttpCo
31
35
/// An external engine api client
32
36
#[ derive( Debug , Clone ) ]
33
37
pub struct EngineClient {
34
- /// The inner provider
35
- provider : RootProvider < Http < HyperAuthClient > , AnyNetwork > ,
38
+ /// The L2 engine provider.
39
+ engine : RootProvider < Http < HyperAuthClient > , AnyNetwork > ,
40
+ /// The L2 chain provider.
41
+ rpc : AlloyL2ChainProvider ,
36
42
}
37
43
38
44
impl EngineClient {
39
45
/// Creates a new [`EngineClient`] from the provided [Url] and [JwtSecret].
40
- pub fn new_http ( url : Url , jwt : JwtSecret ) -> Self {
46
+ pub fn new_http ( engine : Url , rpc : Url , cfg : Arc < RollupConfig > , jwt : JwtSecret ) -> Self {
41
47
let hyper_client = Client :: builder ( TokioExecutor :: new ( ) ) . build_http :: < Full < Bytes > > ( ) ;
42
48
43
49
let auth_layer = AuthLayer :: new ( jwt) ;
44
50
let service = ServiceBuilder :: new ( ) . layer ( auth_layer) . service ( hyper_client) ;
45
51
46
52
let layer_transport = HyperClient :: with_service ( service) ;
47
- let http_hyper = Http :: with_client ( layer_transport, url ) ;
53
+ let http_hyper = Http :: with_client ( layer_transport, engine ) ;
48
54
let rpc_client = RpcClient :: new ( http_hyper, true ) ;
49
- let provider = RootProvider :: < _ , AnyNetwork > :: new ( rpc_client) ;
55
+ let engine = RootProvider :: < _ , AnyNetwork > :: new ( rpc_client) ;
50
56
51
- Self { provider }
57
+ let rpc = ReqwestProvider :: new_http ( rpc) ;
58
+ let rpc = AlloyL2ChainProvider :: new ( rpc, cfg) ;
59
+ Self { engine, rpc }
52
60
}
53
61
}
54
62
@@ -60,15 +68,15 @@ impl Engine for EngineClient {
60
68
& self ,
61
69
payload_id : PayloadId ,
62
70
) -> Result < OpExecutionPayloadEnvelopeV3 , Self :: Error > {
63
- self . provider . get_payload_v3 ( payload_id) . await . map_err ( |_| EngineApiError :: PayloadError )
71
+ self . engine . get_payload_v3 ( payload_id) . await . map_err ( |_| EngineApiError :: PayloadError )
64
72
}
65
73
66
74
async fn forkchoice_update (
67
75
& self ,
68
76
state : ForkchoiceState ,
69
77
attr : Option < OpPayloadAttributes > ,
70
78
) -> Result < ForkchoiceUpdated , Self :: Error > {
71
- self . provider
79
+ self . engine
72
80
. fork_choice_updated_v2 ( state, attr)
73
81
. await
74
82
. map_err ( |_| EngineApiError :: PayloadError )
@@ -79,24 +87,31 @@ impl Engine for EngineClient {
79
87
payload : ExecutionPayloadV3 ,
80
88
parent_beacon_block_root : B256 ,
81
89
) -> Result < PayloadStatus , Self :: Error > {
82
- self . provider
90
+ self . engine
83
91
. new_payload_v3 ( payload, parent_beacon_block_root)
84
92
. await
85
93
. map_err ( |_| EngineApiError :: PayloadError )
86
94
}
87
95
88
- async fn l2_block_ref_by_label ( & self , _: BlockNumberOrTag ) -> Result < L2BlockInfo , Self :: Error > {
89
- // Convert the payload into an L2 block info.
90
- // go impl uses an L2 client and fetches block by number, converting block to payload and
91
- // payload to L2 block info.
92
- todo ! ( "implement l2_block_ref_by_label for the engine client" )
96
+ async fn l2_block_ref_by_label (
97
+ & mut self ,
98
+ numtag : BlockNumberOrTag ,
99
+ ) -> Result < L2BlockInfo , Self :: Error > {
100
+ let number = match numtag {
101
+ BlockNumberOrTag :: Number ( n) => n,
102
+ BlockNumberOrTag :: Latest => {
103
+ self . rpc . latest_block_number ( ) . await . map_err ( |_| EngineApiError :: PayloadError ) ?
104
+ }
105
+ _ => return Err ( EngineApiError :: PayloadError ) ,
106
+ } ;
107
+ self . rpc . l2_block_info_by_number ( number) . await . map_err ( |_| EngineApiError :: PayloadError )
93
108
}
94
109
}
95
110
96
111
impl std:: ops:: Deref for EngineClient {
97
112
type Target = RootProvider < Http < HyperAuthClient > , AnyNetwork > ;
98
113
99
114
fn deref ( & self ) -> & Self :: Target {
100
- & self . provider
115
+ & self . engine
101
116
}
102
117
}
0 commit comments