@@ -26,7 +26,7 @@ pub async fn consensus_notification(
26
26
let consensus_state: ConsensusState =
27
27
ConsensusState :: decode ( & mut & consensus_state_serialized[ ..] ) ?;
28
28
29
- let trusted_state: TrustedState = consensus_state. tendermint_state . into ( ) ;
29
+ let trusted_state: TrustedState = consensus_state. clone ( ) . tendermint_state . into ( ) ;
30
30
31
31
let untrusted_header = client. prover . signed_header ( latest_height) . await ?;
32
32
@@ -42,46 +42,9 @@ pub async fn consensus_notification(
42
42
true ,
43
43
) ;
44
44
45
- let ( mut milestone_number, mut milestone) = client. prover . get_latest_milestone ( ) . await ?;
46
- let query_height = untrusted_header. header . height . value ( ) - 1 ;
47
- let mut milestone_proof =
48
- client. prover . get_milestone_proof ( milestone_number, query_height) . await ?;
49
-
50
- if milestone_proof. value . is_empty ( ) {
51
- milestone_number -= 1 ;
52
- milestone_proof = client. prover . get_milestone_proof ( milestone_number, query_height) . await ?;
53
-
54
- milestone = ismp_polygon:: Milestone :: proto_decode ( & milestone_proof. value )
55
- . map_err ( |e| anyhow:: anyhow!( "failed to decode milestone: {}" , e) ) ?;
56
- }
57
-
58
- let maybe_milestone_update = if milestone. end_block > consensus_state. last_finalized_block {
59
- let evm_header = client
60
- . prover
61
- . fetch_header ( milestone. end_block )
62
- . await ?
63
- . ok_or_else ( || anyhow:: anyhow!( "EVM header not found" ) ) ?;
64
-
65
- let merkle_proof = milestone_proof
66
- . clone ( )
67
- . proof
68
- . map ( |p| convert_tm_to_ics_merkle_proof :: < ICS23HostFunctions > ( & p) )
69
- . transpose ( )
70
- . map_err ( |_| anyhow:: anyhow!( "bad client state proof" ) ) ?
71
- . ok_or_else ( || anyhow:: anyhow!( "proof not found" ) ) ?;
72
-
73
- let proof = CommitmentProofBytes :: try_from ( merkle_proof)
74
- . map_err ( |e| anyhow:: anyhow!( "bad client state proof: {}" , e) ) ?;
75
-
76
- Some ( ismp_polygon:: MilestoneUpdate {
77
- evm_header,
78
- milestone_number,
79
- ics23_state_proof : proof. into ( ) ,
80
- milestone,
81
- } )
82
- } else {
83
- None
84
- } ;
45
+ let maybe_milestone_update =
46
+ build_milestone_update ( client, untrusted_header. header . height . value ( ) , & consensus_state)
47
+ . await ?;
85
48
86
49
match validator_set_hash_match. is_ok ( ) && next_validator_set_hash_match. is_ok ( ) {
87
50
true => {
@@ -138,6 +101,16 @@ pub async fn consensus_notification(
138
101
let matched_height = height;
139
102
let matched_header = matched_header. expect ( "Header must be present if found" ) ;
140
103
let next_validators = client. prover . next_validators ( matched_height) . await ?;
104
+
105
+ // Also attempt to construct a milestone update corresponding to the matched header
106
+ // height
107
+ let maybe_milestone_update = build_milestone_update (
108
+ client,
109
+ matched_header. header . height . value ( ) ,
110
+ & consensus_state,
111
+ )
112
+ . await ?;
113
+
141
114
return Ok ( Some ( PolygonConsensusUpdate {
142
115
tendermint_proof : CodecConsensusProof :: from ( & ConsensusProof :: new (
143
116
matched_header. clone ( ) ,
@@ -147,7 +120,7 @@ pub async fn consensus_notification(
147
120
Some ( next_validators)
148
121
} ,
149
122
) ) ,
150
- milestone_update : None ,
123
+ milestone_update : maybe_milestone_update ,
151
124
} ) ) ;
152
125
} else {
153
126
log:: error!( target: "tesseract" , "Fatal error, failed to find any header that matches onchain validator set" ) ;
@@ -158,6 +131,62 @@ pub async fn consensus_notification(
158
131
Ok ( None )
159
132
}
160
133
134
+ async fn build_milestone_update (
135
+ client : & PolygonPosHost ,
136
+ reference_height : u64 ,
137
+ consensus_state : & ConsensusState ,
138
+ ) -> anyhow:: Result < Option < ismp_polygon:: MilestoneUpdate > > {
139
+ let query_height = reference_height. saturating_sub ( 1 ) ;
140
+ let latest_milestone_at_height =
141
+ client. prover . get_latest_milestone_at_height ( query_height) . await ?;
142
+
143
+ let ( milestone_number, milestone) = match latest_milestone_at_height {
144
+ Some ( ( number, milestone) ) => ( number, milestone) ,
145
+ None => {
146
+ log:: warn!(
147
+ target: "tesseract" ,
148
+ "No milestone found at height {}, falling back to current latest" ,
149
+ reference_height
150
+ ) ;
151
+ return Ok ( None ) ;
152
+ } ,
153
+ } ;
154
+
155
+ let milestone_proof = client. prover . get_milestone_proof ( milestone_number, query_height) . await ?;
156
+
157
+ if milestone_proof. value . is_empty ( ) {
158
+ return Ok ( None ) ;
159
+ }
160
+
161
+ if milestone. end_block > consensus_state. last_finalized_block {
162
+ let evm_header = client
163
+ . prover
164
+ . fetch_header ( milestone. end_block )
165
+ . await ?
166
+ . ok_or_else ( || anyhow:: anyhow!( "EVM header not found" ) ) ?;
167
+
168
+ let merkle_proof = milestone_proof
169
+ . clone ( )
170
+ . proof
171
+ . map ( |p| convert_tm_to_ics_merkle_proof :: < ICS23HostFunctions > ( & p) )
172
+ . transpose ( )
173
+ . map_err ( |_| anyhow:: anyhow!( "bad client state proof" ) ) ?
174
+ . ok_or_else ( || anyhow:: anyhow!( "proof not found" ) ) ?;
175
+
176
+ let proof = CommitmentProofBytes :: try_from ( merkle_proof)
177
+ . map_err ( |e| anyhow:: anyhow!( "bad client state proof: {}" , e) ) ?;
178
+
179
+ Ok ( Some ( ismp_polygon:: MilestoneUpdate {
180
+ evm_header,
181
+ milestone_number,
182
+ ics23_state_proof : proof. into ( ) ,
183
+ milestone,
184
+ } ) )
185
+ } else {
186
+ Ok ( None )
187
+ }
188
+ }
189
+
161
190
pub fn convert_tm_to_ics_merkle_proof < H > (
162
191
tm_proof : & ProofOps ,
163
192
) -> Result < MerkleProof , anyhow:: Error > {
0 commit comments