1
- use crate :: Contract ;
1
+ use crate :: types :: { Qualified , QueryHeight } ;
2
2
use crate :: * ;
3
+ use crate :: { types:: QueryPacketEventDataRequest , Contract } ;
4
+ use ibc:: events:: { IbcEventType , WithBlockDataType } ;
3
5
use ibc:: {
4
6
core:: {
5
7
ics03_connection:: connection:: { ConnectionEnd , IdentifiedConnectionEnd } ,
@@ -13,7 +15,6 @@ use ibc::{
13
15
} ,
14
16
Height ,
15
17
} ;
16
- use ibc_proto:: ibc:: core:: channel:: v1:: QueryChannelsRequest ;
17
18
18
19
pub trait Viewer {
19
20
/// Get the latest height of the host chain.
@@ -48,7 +49,7 @@ pub trait Viewer {
48
49
/// Get all connections associated with the given client id.
49
50
fn get_client_connections ( & self , client_id : ClientId ) -> Vec < ConnectionId > ;
50
51
/// Get the channel ends associated with the given query request.
51
- fn get_channels ( & self , request : QueryChannelsRequest ) -> Vec < IdentifiedChannelEnd > ;
52
+ fn get_channels ( & self ) -> Vec < IdentifiedChannelEnd > ;
52
53
/// Get the channel ends associated with the given connection id.
53
54
fn get_connection_channels ( & self , connection_id : ConnectionId ) -> Vec < IdentifiedChannelEnd > ;
54
55
/// Get the packet commitment stored on this host.
@@ -74,6 +75,11 @@ pub trait Viewer {
74
75
fn get_packet_acknowledgements ( & self , port_id : PortId , channel_id : ChannelId ) -> Vec < Sequence > ;
75
76
/// Get the commitment packet stored on this host.
76
77
fn get_commitment_prefix ( & self ) -> CommitmentPrefix ;
78
+ /// Get the packet events associated with the given query request.
79
+ fn get_packet_events (
80
+ & self ,
81
+ request : QueryPacketEventDataRequest ,
82
+ ) -> Vec < ( Height , Vec < IbcEvent > ) > ;
77
83
/// Get the heights that ibc events happened on.
78
84
fn get_ibc_events_heights ( & self ) -> Vec < u64 > ;
79
85
/// Get ibc events happened on the given height.
@@ -236,7 +242,7 @@ impl Viewer for Contract {
236
242
)
237
243
}
238
244
239
- fn get_channels ( & self , request : QueryChannelsRequest ) -> Vec < IdentifiedChannelEnd > {
245
+ fn get_channels ( & self ) -> Vec < IdentifiedChannelEnd > {
240
246
let near_ibc_store = self . near_ibc_store . get ( ) . unwrap ( ) ;
241
247
near_ibc_store
242
248
. channels
@@ -261,6 +267,7 @@ impl Viewer for Contract {
261
267
|channels| {
262
268
channels
263
269
. iter ( )
270
+ . filter ( |key| near_ibc_store. channels . contains_key ( key) )
264
271
. map ( |( port_id, channel_id) | IdentifiedChannelEnd {
265
272
port_id : port_id. clone ( ) ,
266
273
channel_id : channel_id. clone ( ) ,
@@ -356,6 +363,55 @@ impl Viewer for Contract {
356
363
. unwrap_or_default ( )
357
364
}
358
365
366
+ fn get_packet_events (
367
+ & self ,
368
+ request : QueryPacketEventDataRequest ,
369
+ ) -> Vec < ( Height , Vec < IbcEvent > ) > {
370
+ let mut result: Vec < ( Height , Vec < IbcEvent > ) > = Vec :: new ( ) ;
371
+ let ( target_height, need_to_search_in_range) = match & request. height {
372
+ Qualified :: SmallerEqual ( query_height) => match query_height {
373
+ QueryHeight :: Latest => ( self . ibc_events_history . latest_key ( ) , true ) ,
374
+ QueryHeight :: Specific ( height) => ( Some ( height. revision_height ( ) ) , true ) ,
375
+ } ,
376
+ Qualified :: Equal ( query_height) => match query_height {
377
+ QueryHeight :: Latest => ( self . ibc_events_history . latest_key ( ) , false ) ,
378
+ QueryHeight :: Specific ( height) => ( Some ( height. revision_height ( ) ) , false ) ,
379
+ } ,
380
+ } ;
381
+ if need_to_search_in_range {
382
+ if let Some ( height) = target_height {
383
+ self . ibc_events_history
384
+ . keys ( )
385
+ . iter ( )
386
+ . filter ( |key| key. is_some ( ) )
387
+ . map ( |key| key. unwrap ( ) )
388
+ . filter ( |key| * key <= height)
389
+ . for_each ( |key| {
390
+ gether_ibc_events_with_height (
391
+ & mut result,
392
+ key,
393
+ self . ibc_events_history
394
+ . get_value_by_key ( & key)
395
+ . map ( |events| {
396
+ Vec :: < IbcEvent > :: try_from_slice ( & events)
397
+ . unwrap_or_else ( |_| vec ! [ ] )
398
+ } )
399
+ . unwrap_or_else ( || vec ! [ ] ) ,
400
+ & request,
401
+ ) ;
402
+ } ) ;
403
+ }
404
+ } else {
405
+ let events = self
406
+ . ibc_events_history
407
+ . get_value_by_key ( & target_height. unwrap ( ) )
408
+ . map_or_else ( || vec ! [ ] , |events| events) ;
409
+ let ibc_events = Vec :: < IbcEvent > :: try_from_slice ( & events) . unwrap_or_else ( |_| vec ! [ ] ) ;
410
+ gether_ibc_events_with_height ( & mut result, target_height. unwrap ( ) , ibc_events, & request)
411
+ }
412
+ result
413
+ }
414
+
359
415
fn get_ibc_events_heights ( & self ) -> Vec < u64 > {
360
416
self . ibc_events_history
361
417
. keys ( )
@@ -373,3 +429,47 @@ impl Viewer for Contract {
373
429
Vec :: < IbcEvent > :: try_from_slice ( & raw_events) . unwrap_or_else ( |_| vec ! [ ] )
374
430
}
375
431
}
432
+
433
+ fn gether_ibc_events_with_height (
434
+ result : & mut Vec < ( Height , Vec < IbcEvent > ) > ,
435
+ height : u64 ,
436
+ ibc_events : Vec < IbcEvent > ,
437
+ request : & QueryPacketEventDataRequest ,
438
+ ) {
439
+ let events = ibc_events
440
+ . iter ( )
441
+ . filter ( |event| match request. event_id {
442
+ WithBlockDataType :: CreateClient => event. event_type ( ) == IbcEventType :: CreateClient ,
443
+ WithBlockDataType :: UpdateClient => event. event_type ( ) == IbcEventType :: UpdateClient ,
444
+ WithBlockDataType :: SendPacket => event. event_type ( ) == IbcEventType :: SendPacket ,
445
+ WithBlockDataType :: WriteAck => event. event_type ( ) == IbcEventType :: WriteAck ,
446
+ } )
447
+ . filter ( |event| match event {
448
+ IbcEvent :: CreateClient ( _) => true ,
449
+ IbcEvent :: UpdateClient ( _) => true ,
450
+ IbcEvent :: ReceivePacket ( receive_packet) => {
451
+ request. source_port_id . eq ( receive_packet. src_port_id ( ) )
452
+ && request
453
+ . source_channel_id
454
+ . eq ( receive_packet. src_channel_id ( ) )
455
+ && request. destination_port_id . eq ( receive_packet. dst_port_id ( ) )
456
+ && request
457
+ . destination_channel_id
458
+ . eq ( receive_packet. dst_channel_id ( ) )
459
+ && request. sequences . contains ( & receive_packet. sequence ( ) )
460
+ }
461
+ IbcEvent :: WriteAcknowledgement ( write_ack) => {
462
+ request. source_port_id . eq ( write_ack. src_port_id ( ) )
463
+ && request. source_channel_id . eq ( write_ack. src_channel_id ( ) )
464
+ && request. destination_port_id . eq ( write_ack. dst_port_id ( ) )
465
+ && request
466
+ . destination_channel_id
467
+ . eq ( write_ack. dst_channel_id ( ) )
468
+ && request. sequences . contains ( & write_ack. sequence ( ) )
469
+ }
470
+ _ => false ,
471
+ } )
472
+ . map ( |event| event. clone ( ) )
473
+ . collect_vec ( ) ;
474
+ result. push ( ( Height :: new ( 0 , height) . unwrap ( ) , events) ) ;
475
+ }
0 commit comments