3
3
4
4
pub mod message;
5
5
6
- use crate :: message:: { ContractEventNotification , Event , Notification , ThinBlock } ;
6
+ use crate :: message:: {
7
+ ContractEventNotification , ContractEventNotification2 , Event , Event2 , Notification , ThinBlock ,
8
+ } ;
7
9
use anyhow:: { format_err, Result } ;
8
10
use starcoin_logger:: prelude:: * ;
9
11
use starcoin_service_registry:: { ActorService , EventHandler , ServiceContext , ServiceFactory } ;
10
12
use starcoin_storage:: { Storage , Store } ;
11
13
use starcoin_types:: block:: Block ;
12
14
use starcoin_types:: system_events:: NewHeadBlock ;
15
+ use starcoin_vm2_storage:: { Storage as Storage2 , Store as Store2 } ;
13
16
use std:: sync:: Arc ;
14
17
15
18
/// ChainNotify watch `NewHeadBlock` message from bus,
16
19
/// and then reproduce `Notification<ThinBlock>` and `Notification<Arc<[Event]>>` message to bus.
17
20
/// User can subscribe the two notification to watch onchain events.
18
21
pub struct ChainNotifyHandlerService {
19
22
store : Arc < dyn Store > ,
23
+ store2 : Arc < dyn Store2 > ,
20
24
}
21
25
22
26
impl ChainNotifyHandlerService {
23
- pub fn new ( store : Arc < dyn Store > ) -> Self {
24
- Self { store }
27
+ pub fn new ( store : Arc < dyn Store > , store2 : Arc < dyn Store2 > ) -> Self {
28
+ Self { store, store2 }
25
29
}
26
30
}
27
31
@@ -30,7 +34,8 @@ impl ServiceFactory<Self> for ChainNotifyHandlerService {
30
34
ctx : & mut ServiceContext < ChainNotifyHandlerService > ,
31
35
) -> Result < ChainNotifyHandlerService > {
32
36
let storage = ctx. get_shared :: < Arc < Storage > > ( ) ?;
33
- Ok ( Self :: new ( storage) )
37
+ let storage2 = ctx. get_shared :: < Arc < Storage2 > > ( ) ?;
38
+ Ok ( Self :: new ( storage, storage2) )
34
39
}
35
40
}
36
41
@@ -58,7 +63,7 @@ impl EventHandler<Self, NewHeadBlock> for ChainNotifyHandlerService {
58
63
self . notify_new_block ( block, ctx) ;
59
64
60
65
// notify events
61
- if let Err ( e) = self . notify_events ( block, self . store . clone ( ) , ctx) {
66
+ if let Err ( e) = self . notify_events ( block, self . store . clone ( ) , self . store2 . clone ( ) , ctx) {
62
67
error ! ( target: "pubsub" , "fail to notify events to client, err: {}" , & e) ;
63
68
}
64
69
}
@@ -77,18 +82,23 @@ impl ChainNotifyHandlerService {
77
82
& self ,
78
83
block : & Block ,
79
84
store : Arc < dyn Store > ,
85
+ store2 : Arc < dyn Store2 > ,
80
86
ctx : & mut ServiceContext < Self > ,
81
87
) -> Result < ( ) > {
82
88
let block_number = block. header ( ) . number ( ) ;
83
89
let block_id = block. id ( ) ;
84
90
let txn_info_ids = store. get_block_txn_info_ids ( block_id) ?;
85
91
let mut all_events: Vec < Event > = vec ! [ ] ;
92
+ let mut all_events2 = vec ! [ ] ;
86
93
for txn_info_id in txn_info_ids. into_iter ( ) . rev ( ) {
87
94
let txn_info = store
88
95
. get_transaction_info ( txn_info_id) ?
89
96
. ok_or_else ( || format_err ! ( "cannot find txn info by it's id {}" , & txn_info_id) ) ?;
90
97
// get events directly by txn_info_id
91
- let events = store. get_contract_events ( txn_info_id) ?. unwrap_or_default ( ) ;
98
+ let ( in_vm1, events) = store
99
+ . get_contract_events ( txn_info_id) ?
100
+ . map ( |e| ( true , e) )
101
+ . unwrap_or ( ( false , vec ! [ ] ) ) ;
92
102
all_events. extend ( events. into_iter ( ) . enumerate ( ) . map ( |( idx, evt) | {
93
103
Event :: new (
94
104
block_id,
@@ -100,9 +110,26 @@ impl ChainNotifyHandlerService {
100
110
evt,
101
111
)
102
112
} ) ) ;
113
+ if !in_vm1 {
114
+ let events = store2. get_contract_events ( txn_info_id) ?. unwrap_or_default ( ) ;
115
+ all_events2. extend ( events. into_iter ( ) . enumerate ( ) . map ( |( idx, evt) | {
116
+ Event2 :: new (
117
+ block_id,
118
+ block_number,
119
+ txn_info. transaction_hash ( ) ,
120
+ Some ( txn_info. transaction_index ) ,
121
+ Some ( txn_info. transaction_global_index ) ,
122
+ Some ( idx as u32 ) ,
123
+ evt,
124
+ )
125
+ } ) ) ;
126
+ }
103
127
}
104
- let events_notification: ContractEventNotification =
105
- Notification ( ( block. header . state_root ( ) , all_events. into ( ) ) ) ;
128
+ let events_notification: ContractEventNotification = Notification ( (
129
+ block. header . state_root ( ) ,
130
+ all_events. into ( ) ,
131
+ all_events2. into ( ) ,
132
+ ) ) ;
106
133
ctx. broadcast ( events_notification) ;
107
134
Ok ( ( ) )
108
135
}
0 commit comments