2
2
3
3
use std:: { cmp:: Reverse , sync:: Arc } ;
4
4
5
+ use anyhow:: anyhow;
5
6
use futures:: StreamExt ;
6
7
use poem_openapi:: { payload:: Json , ApiResponse } ;
7
8
use tracing:: error;
8
9
9
10
use crate :: {
10
11
db:: index:: {
11
12
queries:: registrations:: {
12
- get_from_stake_addr:: { GetRegistrationParams , GetRegistrationQuery } ,
13
+ get_from_stake_addr:: GetRegistrationQuery ,
13
14
get_from_stake_hash:: { GetStakeAddrParams , GetStakeAddrQuery } ,
14
15
get_from_vote_key:: { GetStakeAddrFromVoteKeyParams , GetStakeAddrFromVoteKeyQuery } ,
15
16
get_invalid:: { GetInvalidRegistrationParams , GetInvalidRegistrationQuery } ,
@@ -21,7 +22,9 @@ use crate::{
21
22
Cip36Info , Cip36Reporting , Cip36ReportingList , InvalidRegistrationsReport ,
22
23
} ,
23
24
responses:: WithErrorResponses ,
25
+ types:: headers:: retry_after:: RetryAfterOption ,
24
26
} ,
27
+ utils:: ed25519,
25
28
} ;
26
29
27
30
/// Endpoint responses.
@@ -51,18 +54,10 @@ pub(crate) type SingleRegistrationResponse = WithErrorResponses<ResponseSingleRe
51
54
/// All responses voting key
52
55
pub ( crate ) type MultipleRegistrationResponse = WithErrorResponses < ResponseMultipleRegistrations > ;
53
56
54
- /// Get latest registration given a stake address
57
+ /// Get latest registration given a stake public key
55
58
pub ( crate ) async fn get_latest_registration_from_stake_addr (
56
- stake_addr : String , persistent : bool ,
59
+ stake_pub_key : & ed25519_dalek :: VerifyingKey , persistent : bool ,
57
60
) -> SingleRegistrationResponse {
58
- let stake_addr = match hex:: decode ( stake_addr) {
59
- Ok ( stake_addr) => stake_addr,
60
- Err ( err) => {
61
- error ! ( id="get_latest_registration_from_stake_addr" , error=?err, "Failed to decode stake addr" ) ;
62
- return ResponseSingleRegistration :: NotFound . into ( ) ;
63
- } ,
64
- } ;
65
-
66
61
let Some ( session) = CassandraSession :: get ( persistent) else {
67
62
error ! (
68
63
id = "get_latest_registration_from_stake_addr" ,
@@ -72,7 +67,7 @@ pub(crate) async fn get_latest_registration_from_stake_addr(
72
67
} ;
73
68
74
69
let registration =
75
- match latest_registration_from_stake_addr ( stake_addr . clone ( ) , session. clone ( ) ) . await {
70
+ match latest_registration_from_stake_addr ( stake_pub_key , session. clone ( ) ) . await {
76
71
Ok ( registrations) => registrations,
77
72
Err ( err) => {
78
73
error ! (
@@ -84,13 +79,10 @@ pub(crate) async fn get_latest_registration_from_stake_addr(
84
79
} ,
85
80
} ;
86
81
87
- let invalids_report = match get_invalid_registrations (
88
- registration. stake_address . clone ( ) ,
89
- registration. slot_no . into ( ) ,
90
- session,
91
- )
92
- . await
93
- {
82
+ let raw_invalids =
83
+ get_invalid_registrations ( stake_pub_key, registration. slot_no . into ( ) , session) . await ;
84
+
85
+ let invalids_report = match raw_invalids {
94
86
Ok ( invalids) => invalids,
95
87
Err ( err) => {
96
88
error ! (
@@ -109,17 +101,19 @@ pub(crate) async fn get_latest_registration_from_stake_addr(
109
101
110
102
/// Get latest registration given a stake addr
111
103
async fn latest_registration_from_stake_addr (
112
- stake_addr : Vec < u8 > , session : Arc < CassandraSession > ,
104
+ stake_pub_key : & ed25519_dalek :: VerifyingKey , session : Arc < CassandraSession > ,
113
105
) -> anyhow:: Result < Cip36Info > {
114
- sort_latest_registration ( get_all_registrations_from_stake_addr ( session, stake_addr) . await ?)
106
+ sort_latest_registration (
107
+ get_all_registrations_from_stake_pub_key ( session, stake_pub_key) . await ?,
108
+ )
115
109
}
116
110
117
111
/// Get all cip36 registrations for a given stake address.
118
- async fn get_all_registrations_from_stake_addr (
119
- session : Arc < CassandraSession > , stake_addr : Vec < u8 > ,
112
+ async fn get_all_registrations_from_stake_pub_key (
113
+ session : Arc < CassandraSession > , stake_pub_key : & ed25519_dalek :: VerifyingKey ,
120
114
) -> Result < Vec < Cip36Info > , anyhow:: Error > {
121
115
let mut registrations_iter =
122
- GetRegistrationQuery :: execute ( & session, GetRegistrationParams :: new ( stake_addr ) ) . await ?;
116
+ GetRegistrationQuery :: execute ( & session, stake_pub_key . into ( ) ) . await ?;
123
117
let mut registrations = Vec :: new ( ) ;
124
118
while let Some ( row) = registrations_iter. next ( ) . await {
125
119
let row = row?;
@@ -137,7 +131,7 @@ async fn get_all_registrations_from_stake_addr(
137
131
} ;
138
132
139
133
let cip36 = Cip36Info {
140
- stake_address : hex :: encode ( row. stake_address ) ,
134
+ stake_pub_key : row. stake_address . try_into ( ) ? ,
141
135
nonce,
142
136
slot_no,
143
137
txn : row. txn ,
@@ -162,13 +156,12 @@ fn sort_latest_registration(mut registrations: Vec<Cip36Info>) -> anyhow::Result
162
156
163
157
/// Get invalid registrations for stake addr after given slot no
164
158
async fn get_invalid_registrations (
165
- stake_addr : String , slot_no : num_bigint:: BigInt , session : Arc < CassandraSession > ,
159
+ stake_pub_key : & ed25519_dalek:: VerifyingKey , slot_no : num_bigint:: BigInt ,
160
+ session : Arc < CassandraSession > ,
166
161
) -> anyhow:: Result < Vec < InvalidRegistrationsReport > > {
167
- let stake_addr = hex:: decode ( stake_addr) ?;
168
-
169
162
let mut invalid_registrations_iter = GetInvalidRegistrationQuery :: execute (
170
163
& session,
171
- GetInvalidRegistrationParams :: new ( stake_addr , slot_no) ,
164
+ GetInvalidRegistrationParams :: new ( stake_pub_key . as_bytes ( ) . to_vec ( ) , slot_no) ,
172
165
)
173
166
. await ?;
174
167
let mut invalid_registrations = Vec :: new ( ) ;
@@ -177,7 +170,7 @@ async fn get_invalid_registrations(
177
170
178
171
invalid_registrations. push ( InvalidRegistrationsReport {
179
172
error_report : row. error_report ,
180
- stake_address : hex :: encode ( row. stake_address ) ,
173
+ stake_address : row. stake_address . try_into ( ) ? ,
181
174
vote_key : hex:: encode ( row. vote_key ) ,
182
175
payment_address : hex:: encode ( row. payment_address ) ,
183
176
is_payable : row. is_payable ,
@@ -212,11 +205,9 @@ pub(crate) async fn get_latest_registration_from_stake_key_hash(
212
205
} ;
213
206
214
207
let Some ( session) = CassandraSession :: get ( persistent) else {
215
- error ! (
216
- id = "get_latest_registration_from_stake_key_hash_db_session" ,
217
- "Failed to acquire db session"
218
- ) ;
219
- return ResponseSingleRegistration :: NotFound . into ( ) ;
208
+ error ! ( "Failed to acquire db session" ) ;
209
+ let err = anyhow:: anyhow!( "Failed to acquire db session" ) ;
210
+ return SingleRegistrationResponse :: service_unavailable ( & err, RetryAfterOption :: Default ) ;
220
211
} ;
221
212
222
213
// Get stake addr associated with give stake hash
@@ -246,8 +237,17 @@ pub(crate) async fn get_latest_registration_from_stake_key_hash(
246
237
} ,
247
238
} ;
248
239
240
+ let stake_pub_key = match ed25519:: verifying_key_from_vec ( & row. stake_address ) {
241
+ Ok ( v) => v,
242
+ Err ( err) => {
243
+ error ! ( error=?err, "Invalid Stake Public Key in database." ) ;
244
+ let err = anyhow ! ( err) ;
245
+ return SingleRegistrationResponse :: internal_error ( & err) ;
246
+ } ,
247
+ } ;
248
+
249
249
let registration = match latest_registration_from_stake_addr (
250
- row . stake_address . clone ( ) ,
250
+ & stake_pub_key ,
251
251
session. clone ( ) ,
252
252
)
253
253
. await
@@ -266,7 +266,7 @@ pub(crate) async fn get_latest_registration_from_stake_key_hash(
266
266
// include any erroneous registrations which occur AFTER the slot# of the last valid
267
267
// registration
268
268
let invalids_report = match get_invalid_registrations (
269
- registration . stake_address . clone ( ) ,
269
+ & stake_pub_key ,
270
270
registration. slot_no . into ( ) ,
271
271
session,
272
272
)
@@ -347,12 +347,22 @@ pub(crate) async fn get_associated_vote_key_registrations(
347
347
} ,
348
348
} ;
349
349
350
+ let stake_pub_key = match ed25519:: verifying_key_from_vec ( & row. stake_address ) {
351
+ Ok ( k) => k,
352
+ Err ( err) => {
353
+ error ! (
354
+ id="get_associated_vote_key_registrations_latest_registration" ,
355
+ error=?err,
356
+ "Not a valid staking public key"
357
+ ) ;
358
+ return ResponseMultipleRegistrations :: NotFound . into ( ) ;
359
+ } ,
360
+ } ;
361
+
350
362
// We have the stake addr associated with vote key, now get all registrations with the
351
363
// stake addr.
352
364
let registrations =
353
- match get_all_registrations_from_stake_addr ( session. clone ( ) , row. stake_address . clone ( ) )
354
- . await
355
- {
365
+ match get_all_registrations_from_stake_pub_key ( session. clone ( ) , & stake_pub_key) . await {
356
366
Ok ( registration) => registration,
357
367
Err ( err) => {
358
368
error ! (
@@ -375,7 +385,7 @@ pub(crate) async fn get_associated_vote_key_registrations(
375
385
376
386
for registration in redacted_registrations {
377
387
let invalids_report = match get_invalid_registrations (
378
- registration . stake_address . clone ( ) ,
388
+ & stake_pub_key ,
379
389
registration. slot_no . into ( ) ,
380
390
session. clone ( ) ,
381
391
)
0 commit comments