Skip to content

Commit 282b13e

Browse files
Seulgi Kimmergify[bot]
authored andcommitted
Add a close block event handler to ActionHandler
1 parent e2af16f commit 282b13e

File tree

5 files changed

+82
-12
lines changed

5 files changed

+82
-12
lines changed

core/src/block.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ impl<'x> OpenBlock<'x> {
227227
warn!("Encountered error on closing the block: {}", e);
228228
return Err(e)
229229
}
230+
for handler in self.engine.action_handlers() {
231+
handler.on_close_block(self.block.state_mut()).map_err(|e| {
232+
warn!("Encountered error in {}::on_close_block", handler.name());
233+
e
234+
})?;
235+
}
236+
230237
let state_root = self.block.state.commit().map_err(|e| {
231238
warn!("Encountered error on state commit: {}", e);
232239
e
@@ -253,6 +260,12 @@ impl<'x> OpenBlock<'x> {
253260
warn!("Encountered error on closing the block: {}", e);
254261
return Err(e)
255262
}
263+
for handler in self.engine.action_handlers() {
264+
handler.on_close_block(self.block.state_mut()).map_err(|e| {
265+
warn!("Encountered error in {}::on_close_block", handler.name());
266+
e
267+
})?;
268+
}
256269

257270
let state_root = self.block.state.commit().map_err(|e| {
258271
warn!("Encountered error on state commit: {}", e);

core/src/consensus/stake/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ fn parse_env_var_enable_delegations() -> bool {
7171
}
7272

7373
impl ActionHandler for Stake {
74+
fn name(&self) -> &'static str {
75+
"stake handler"
76+
}
77+
7478
fn handler_id(&self) -> u64 {
7579
CUSTOM_ACTION_HANDLER_ID
7680
}
@@ -113,6 +117,10 @@ impl ActionHandler for Stake {
113117
Action::decode(&UntrustedRlp::new(bytes)).map_err(|err| SyntaxError::InvalidCustomAction(err.to_string()))?;
114118
Ok(())
115119
}
120+
121+
fn on_close_block(&self, _state: &mut TopLevelState) -> StateResult<()> {
122+
Ok(())
123+
}
116124
}
117125

118126
fn transfer_ccs(state: &mut TopLevelState, sender: &Address, receiver: &Address, quantity: u64) -> StateResult<()> {

state/src/action_handler/hit.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,30 +37,40 @@ impl HitHandler {
3737
Self::default()
3838
}
3939

40-
fn address(&self) -> H256 {
41-
ActionDataKeyBuilder::new(CUSTOM_ACTION_HANDLER_ID, 1).append(&"metadata hit").into_key()
40+
fn hit_count(&self) -> H256 {
41+
ActionDataKeyBuilder::new(CUSTOM_ACTION_HANDLER_ID, 1).append(&"hit count").into_key()
42+
}
43+
44+
fn close_count(&self) -> H256 {
45+
ActionDataKeyBuilder::new(CUSTOM_ACTION_HANDLER_ID, 1).append(&"close count").into_key()
4246
}
4347
}
4448

4549
impl ActionHandler for HitHandler {
50+
fn name(&self) -> &'static str {
51+
"hit handler"
52+
}
53+
4654
fn handler_id(&self) -> u64 {
4755
CUSTOM_ACTION_HANDLER_ID
4856
}
4957

5058
fn init(&self, state: &mut TopLevelState) -> StateResult<()> {
51-
let existing = state.action_data(&self.address());
59+
let existing = state.action_data(&self.hit_count());
5260
debug_assert_eq!(Ok(None), existing);
53-
state.update_action_data(&self.address(), 1u32.rlp_bytes().to_vec())?;
61+
state.update_action_data(&self.hit_count(), 1u32.rlp_bytes().to_vec())?;
62+
state.update_action_data(&self.close_count(), 1u32.rlp_bytes().to_vec())?;
5463
Ok(())
5564
}
5665

5766
/// `bytes` must be valid encoding of HitAction
5867
fn execute(&self, bytes: &[u8], state: &mut TopLevelState, _sender: &Address) -> StateResult<()> {
68+
let address = self.hit_count();
5969
let action = HitAction::decode(&UntrustedRlp::new(bytes)).expect("Verification passed");
60-
let action_data = state.action_data(&self.address())?.unwrap_or_default();
70+
let action_data = state.action_data(&address)?.unwrap_or_default();
6171
let prev_counter: u32 = rlp::decode(&*action_data);
6272
let increase = u32::from(action.increase);
63-
state.update_action_data(&self.address(), (prev_counter + increase).rlp_bytes().to_vec())?;
73+
state.update_action_data(&address, (prev_counter + increase).rlp_bytes().to_vec())?;
6474
Ok(())
6575
}
6676

@@ -69,4 +79,12 @@ impl ActionHandler for HitHandler {
6979
.map_err(|err| SyntaxError::InvalidCustomAction(err.to_string()))?;
7080
Ok(())
7181
}
82+
83+
fn on_close_block(&self, state: &mut TopLevelState) -> StateResult<()> {
84+
let address = self.close_count();
85+
let action_data = state.action_data(&address)?.unwrap_or_default();
86+
let prev_counter: u32 = rlp::decode(&*action_data);
87+
state.update_action_data(&address, (prev_counter + 1).rlp_bytes().to_vec())?;
88+
Ok(())
89+
}
7290
}

state/src/action_handler/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use super::TopStateView;
2828
use crate::{StateResult, TopLevelState};
2929

3030
pub trait ActionHandler: Send + Sync {
31+
fn name(&self) -> &'static str;
3132
fn handler_id(&self) -> u64;
3233
fn init(&self, state: &mut TopLevelState) -> StateResult<()>;
3334
fn execute(&self, bytes: &[u8], state: &mut TopLevelState, sender: &Address) -> StateResult<()>;
@@ -38,6 +39,8 @@ pub trait ActionHandler: Send + Sync {
3839
let some_action_data = state.action_data(&key)?.map(Vec::from);
3940
Ok(some_action_data)
4041
}
42+
43+
fn on_close_block(&self, state: &mut TopLevelState) -> StateResult<()>;
4144
}
4245

4346
pub trait FindActionHandler {

test/src/e2e/customAction.test.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,37 @@ describe("customAction", function() {
4545
it("should get initial state", async function() {
4646
const actionData = await node.sdk.rpc.engine.getCustomActionData(
4747
hitActionHandlerId,
48-
["metadata hit"]
48+
["hit count"]
4949
);
5050

5151
expect(actionData).to.be.equal(toHex(RLP.encode(1)));
5252
});
5353

5454
it("should alter state", async function() {
55+
const previousHitData = (await node.sdk.rpc.engine.getCustomActionData(
56+
hitActionHandlerId,
57+
["hit count"]
58+
))!;
59+
const previousHitCount = Buffer.from(
60+
previousHitData,
61+
"hex"
62+
).readUInt8(0);
63+
64+
const previousBlockCloseData = (await node.sdk.rpc.engine.getCustomActionData(
65+
hitActionHandlerId,
66+
["close count"]
67+
))!;
68+
const previousBlockCloseCount = Buffer.from(
69+
previousBlockCloseData,
70+
"hex"
71+
).readUInt8(0);
72+
73+
const increment = 11;
5574
const hash = await node.sdk.rpc.chain.sendSignedTransaction(
5675
node.sdk.core
5776
.createCustomTransaction({
5877
handlerId: hitActionHandlerId,
59-
bytes: RLP.encode([11])
78+
bytes: RLP.encode([increment])
6079
})
6180
.sign({
6281
secret: faucetSecret,
@@ -68,12 +87,21 @@ describe("customAction", function() {
6887
expect(await node.sdk.rpc.chain.containsTransaction(hash)).be.true;
6988
expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null;
7089

71-
const actionData = await node.sdk.rpc.engine.getCustomActionData(
90+
const hitData = await node.sdk.rpc.engine.getCustomActionData(
7291
hitActionHandlerId,
73-
["metadata hit"]
92+
["hit count"]
7493
);
7594

76-
expect(actionData).to.be.equal(toHex(RLP.encode(12)));
95+
expect(hitData).to.be.equal(
96+
toHex(RLP.encode(previousHitCount + increment))
97+
);
98+
const closeData = await node.sdk.rpc.engine.getCustomActionData(
99+
hitActionHandlerId,
100+
["close count"]
101+
);
102+
expect(closeData).to.be.equal(
103+
toHex(RLP.encode(previousBlockCloseCount + 1))
104+
);
77105
});
78106

79107
it("should return null", async function() {
@@ -89,7 +117,7 @@ describe("customAction", function() {
89117
try {
90118
await node.sdk.rpc.engine.getCustomActionData(
91119
hitActionHandlerId,
92-
["metadata hit"],
120+
["hit count"],
93121
99999
94122
);
95123
fail();

0 commit comments

Comments
 (0)