Skip to content

Commit 92c6808

Browse files
committed
enable vm2 contract event notification
1 parent 6eecf56 commit 92c6808

File tree

14 files changed

+89
-56
lines changed

14 files changed

+89
-56
lines changed

Cargo.lock

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chain/chain-notify/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ starcoin-logger = { workspace = true }
55
starcoin-service-registry = { workspace = true }
66
starcoin-storage = { workspace = true }
77
starcoin-types = { workspace = true }
8+
starcoin-vm2-storage = { workspace = true }
9+
starcoin-vm2-vm-types = { workspace = true }
810

911
[package]
1012
authors = { workspace = true }

chain/chain-notify/src/lib.rs

+33-8
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@
33

44
pub mod message;
55

6-
use crate::message::{ContractEventNotification, Event, Notification, ThinBlock};
6+
use crate::message::{ContractEventNotification, Event, Event2, Notification, ThinBlock};
77
use anyhow::{format_err, Result};
88
use starcoin_logger::prelude::*;
99
use starcoin_service_registry::{ActorService, EventHandler, ServiceContext, ServiceFactory};
1010
use starcoin_storage::{Storage, Store};
1111
use starcoin_types::block::Block;
1212
use starcoin_types::system_events::NewHeadBlock;
13+
use starcoin_vm2_storage::{Storage as Storage2, Store as Store2};
1314
use std::sync::Arc;
1415

1516
/// ChainNotify watch `NewHeadBlock` message from bus,
1617
/// and then reproduce `Notification<ThinBlock>` and `Notification<Arc<[Event]>>` message to bus.
1718
/// User can subscribe the two notification to watch onchain events.
1819
pub struct ChainNotifyHandlerService {
1920
store: Arc<dyn Store>,
21+
store2: Arc<dyn Store2>,
2022
}
2123

2224
impl ChainNotifyHandlerService {
23-
pub fn new(store: Arc<dyn Store>) -> Self {
24-
Self { store }
25+
pub fn new(store: Arc<dyn Store>, store2: Arc<dyn Store2>) -> Self {
26+
Self { store, store2 }
2527
}
2628
}
2729

@@ -30,7 +32,8 @@ impl ServiceFactory<Self> for ChainNotifyHandlerService {
3032
ctx: &mut ServiceContext<ChainNotifyHandlerService>,
3133
) -> Result<ChainNotifyHandlerService> {
3234
let storage = ctx.get_shared::<Arc<Storage>>()?;
33-
Ok(Self::new(storage))
35+
let storage2 = ctx.get_shared::<Arc<Storage2>>()?;
36+
Ok(Self::new(storage, storage2))
3437
}
3538
}
3639

@@ -58,7 +61,7 @@ impl EventHandler<Self, NewHeadBlock> for ChainNotifyHandlerService {
5861
self.notify_new_block(block, ctx);
5962

6063
// notify events
61-
if let Err(e) = self.notify_events(block, self.store.clone(), ctx) {
64+
if let Err(e) = self.notify_events(block, self.store.clone(), self.store2.clone(), ctx) {
6265
error!(target: "pubsub", "fail to notify events to client, err: {}", &e);
6366
}
6467
}
@@ -77,18 +80,23 @@ impl ChainNotifyHandlerService {
7780
&self,
7881
block: &Block,
7982
store: Arc<dyn Store>,
83+
store2: Arc<dyn Store2>,
8084
ctx: &mut ServiceContext<Self>,
8185
) -> Result<()> {
8286
let block_number = block.header().number();
8387
let block_id = block.id();
8488
let txn_info_ids = store.get_block_txn_info_ids(block_id)?;
8589
let mut all_events: Vec<Event> = vec![];
90+
let mut all_events2 = vec![];
8691
for txn_info_id in txn_info_ids.into_iter().rev() {
8792
let txn_info = store
8893
.get_transaction_info(txn_info_id)?
8994
.ok_or_else(|| format_err!("cannot find txn info by it's id {}", &txn_info_id))?;
9095
// get events directly by txn_info_id
91-
let events = store.get_contract_events(txn_info_id)?.unwrap_or_default();
96+
let (in_vm1, events) = store
97+
.get_contract_events(txn_info_id)?
98+
.map(|e| (true, e))
99+
.unwrap_or((false, vec![]));
92100
all_events.extend(events.into_iter().enumerate().map(|(idx, evt)| {
93101
Event::new(
94102
block_id,
@@ -100,9 +108,26 @@ impl ChainNotifyHandlerService {
100108
evt,
101109
)
102110
}));
111+
if !in_vm1 {
112+
let events = store2.get_contract_events(txn_info_id)?.unwrap_or_default();
113+
all_events2.extend(events.into_iter().enumerate().map(|(idx, evt)| {
114+
Event2::new(
115+
block_id,
116+
block_number,
117+
txn_info.transaction_hash(),
118+
Some(txn_info.transaction_index),
119+
Some(txn_info.transaction_global_index),
120+
Some(idx as u32),
121+
evt,
122+
)
123+
}));
124+
}
103125
}
104-
let events_notification: ContractEventNotification =
105-
Notification((block.header.state_root(), all_events.into()));
126+
let events_notification: ContractEventNotification = Notification((
127+
block.header.state_root(),
128+
all_events.into(),
129+
all_events2.into(),
130+
));
106131
ctx.broadcast(events_notification);
107132
Ok(())
108133
}

chain/chain-notify/src/message.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
use starcoin_crypto::HashValue;
55
use starcoin_types::block::BlockHeader;
66
use starcoin_types::{block::BlockNumber, contract_event::ContractEvent};
7+
use starcoin_vm2_vm_types::contract_event::ContractEvent as ContractEvent2;
78
use std::sync::Arc;
89

910
#[derive(Debug, Clone)]
1011
pub struct Notification<T>(pub T);
1112

12-
pub type ContractEventNotification = Notification<(HashValue, Arc<[Event]>)>;
13+
pub type ContractEventNotification = Notification<(HashValue, Arc<[Event]>, Arc<[Event2]>)>;
1314
pub type NewHeadEventNotification = Notification<ThinBlock>;
1415

1516
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -46,6 +47,40 @@ impl Event {
4647
}
4748
}
4849

50+
#[derive(Clone, Debug, Eq, PartialEq)]
51+
pub struct Event2 {
52+
pub block_hash: HashValue,
53+
pub block_number: BlockNumber,
54+
pub transaction_hash: HashValue,
55+
// txn index in block
56+
pub transaction_index: Option<u32>,
57+
pub transaction_global_index: Option<u64>,
58+
pub event_index: Option<u32>,
59+
pub contract_event: ContractEvent2,
60+
}
61+
62+
impl Event2 {
63+
pub fn new(
64+
block_hash: HashValue,
65+
block_number: BlockNumber,
66+
transaction_hash: HashValue,
67+
transaction_index: Option<u32>,
68+
transaction_global_index: Option<u64>,
69+
event_index: Option<u32>,
70+
contract_event: ContractEvent2,
71+
) -> Self {
72+
Self {
73+
block_hash,
74+
block_number,
75+
transaction_hash,
76+
transaction_index,
77+
transaction_global_index,
78+
event_index,
79+
contract_event,
80+
}
81+
}
82+
}
83+
4984
/// Block with only txn hashes.
5085
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
5186
pub struct ThinBlock {

miner/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ starcoin-types = { workspace = true }
3131
starcoin-vm2-storage = { workspace = true }
3232
starcoin-vm2-types = { workspace = true }
3333
starcoin-vm2-vm-types = { workspace = true }
34+
starcoin-vm2-account-service = { workspace = true }
3435

3536
[dev-dependencies]
3637
starcoin-network-rpc = { workspace = true }

miner/src/create_block_template/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ impl ServiceFactory<Self> for BlockBuilderService {
7070
.expect("Startup info should exist when service start.");
7171
//TODO support get service ref by AsyncAPI;
7272
let account_service = ctx.service_ref::<AccountService>()?;
73+
// todo: use vm2 account as default?
74+
//let _account_service = ctx.service_ref::<AccountService2>()?;
7375
let miner_account = block_on(async { account_service.get_default_account().await })?
7476
.ok_or_else(|| {
7577
format_err!("Default account should exist when BlockBuilderService start.")

network-rpc/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ starcoin-storage = { workspace = true }
2929
starcoin-types = { workspace = true }
3030
starcoin-state-tree = { workspace = true }
3131
starcoin-vm-types = { workspace = true }
32+
starcoin-vm2-state-service = { workspace = true }
3233

3334
[dev-dependencies]
3435
starcoin-account-api = { workspace = true }

network-rpc/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use starcoin_service_registry::{
2222
use starcoin_state_service::ChainStateService;
2323
use starcoin_storage::{Storage, Store};
2424
use starcoin_txpool::TxPoolService;
25+
use starcoin_vm2_state_service::ChainStateService as ChainStateService2;
2526
use std::sync::Arc;
2627

2728
mod rpc;
@@ -84,6 +85,8 @@ impl ServiceFactory<Self> for NetworkRpcService {
8485
let chain_service = ctx.service_ref::<ChainReaderService>()?.clone();
8586
let txpool_service = ctx.get_shared::<TxPoolService>()?;
8687
let state_service = ctx.service_ref::<ChainStateService>()?.clone();
88+
// todo: register state_service2
89+
let _state_service2 = ctx.service_ref::<ChainStateService2>()?.clone();
8790
let node_config = ctx.get_shared::<Arc<NodeConfig>>()?;
8891
let quotas = node_config.network.network_rpc_quotas.clone();
8992
Ok(Self::new(

node/src/rpc_service_factory.rs

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use starcoin_state_service::ChainStateService;
2323
use starcoin_storage::Storage;
2424
use starcoin_sync::sync::SyncService;
2525
use starcoin_txpool::TxPoolService;
26+
use starcoin_vm2_state_service::ChainStateService as ChainStateService2;
2627
use starcoin_vm2_storage::Storage as Storage2;
2728
use std::sync::Arc;
2829

@@ -63,6 +64,7 @@ impl ServiceFactory<RpcService> for RpcServiceFactory {
6364
.service_ref_opt::<ChainStateService>()?
6465
.map(|service_ref| StateRpcImpl::new(service_ref.clone(), storage.clone()));
6566
let chain_state_service = ctx.service_ref::<ChainStateService>()?.clone();
67+
let _chain_state_service = ctx.service_ref_opt::<ChainStateService2>()?.cloned();
6668
let account_service = ctx.service_ref_opt::<AccountService>()?.cloned();
6769
let account_api = account_service.clone().map(|service_ref| {
6870
AccountRpcImpl::new(

rpc/server/src/module/pubsub.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ pub struct ContractEventHandler {
522522

523523
impl EventHandler<ContractEventNotification> for ContractEventHandler {
524524
fn handle(&self, msg: ContractEventNotification) -> Vec<jsonrpc_core::Result<pubsub::Result>> {
525-
let Notification((state_root, events)) = msg;
525+
let Notification((state_root, events, _events2)) = msg;
526526
let filtered = events
527527
.as_ref()
528528
.iter()

vm2/service/account/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
anyhow = { workspace = true }
33
starcoin-vm2-account = { workspace = true }
44
starcoin-vm2-account-api = { features = ["mock"], workspace = true }
5+
starcoin-chain-notify = { workspace = true }
56
starcoin-config = { workspace = true }
67
starcoin-vm2-crypto = { workspace = true }
78
starcoin-logger = { workspace = true }

vm2/service/account/src/account_events.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Copyright (c) The Starcoin Core Contributors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use crate::message::ContractEventNotification;
54
use anyhow::{Error, Result};
5+
use starcoin_chain_notify::message::ContractEventNotification;
66
use starcoin_logger::prelude::*;
77
use starcoin_service_registry::{ActorService, EventHandler, ServiceContext, ServiceFactory};
88
use starcoin_vm2_account::account_storage::AccountStorage;
@@ -56,7 +56,7 @@ impl EventHandler<Self, ContractEventNotification> for AccountEventService {
5656
return;
5757
}
5858

59-
for i in item.0 .1.as_ref() {
59+
for i in item.0 .2.as_ref() {
6060
let contract_event = &i.contract_event;
6161
if watched_keys.contains(&contract_event.event_key()) {
6262
if let Err(e) = self.handle_contract_event(contract_event) {

vm2/service/account/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
mod account_events;
5-
mod message;
65
mod service;
76

87
pub use account_events::AccountEventService;
9-
pub use message::{ContractEventNotification, Event};
108
pub use service::AccountService;
119
pub use starcoin_vm2_account::account_storage::AccountStorage;

vm2/service/account/src/message.rs

-41
This file was deleted.

0 commit comments

Comments
 (0)