Skip to content

Commit 96cb221

Browse files
authored
[hermes] Fix concurrency issue (#925)
1 parent c4c4a63 commit 96cb221

File tree

6 files changed

+287
-46
lines changed

6 files changed

+287
-46
lines changed

hermes/Cargo.lock

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hermes/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "hermes"
3-
version = "0.1.3"
3+
version = "0.1.4"
44
edition = "2021"
55

66
[dependencies]
@@ -35,6 +35,7 @@ libp2p = { version = "0.42.2", features = [
3535
]}
3636

3737
log = { version = "0.4.17" }
38+
prometheus-client = { version = "0.21.1" }
3839
pyth-sdk = { version = "0.7.0" }
3940

4041
# Parse Wormhole attester price attestations.

hermes/src/store.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ use {
1919
construct_message_states_proofs,
2020
store_wormhole_merkle_verified_message,
2121
},
22-
storage::{
23-
AccumulatorState,
24-
CompletedAccumulatorState,
25-
},
22+
storage::CompletedAccumulatorState,
2623
types::{
2724
ProofSet,
2825
UnixTimestamp,
@@ -150,18 +147,14 @@ impl Store {
150147
Update::AccumulatorMessages(accumulator_messages) => {
151148
let slot = accumulator_messages.slot;
152149
log::info!("Storing accumulator messages for slot {:?}.", slot,);
153-
let mut accumulator_state = self
154-
.storage
155-
.fetch_accumulator_state(slot)
156-
.await?
157-
.unwrap_or(AccumulatorState {
158-
slot,
159-
accumulator_messages: None,
160-
wormhole_merkle_state: None,
161-
});
162-
accumulator_state.accumulator_messages = Some(accumulator_messages);
163150
self.storage
164-
.store_accumulator_state(accumulator_state)
151+
.update_accumulator_state(
152+
slot,
153+
Box::new(|mut state| {
154+
state.accumulator_messages = Some(accumulator_messages);
155+
state
156+
}),
157+
)
165158
.await?;
166159
slot
167160
}

hermes/src/store/proof/wormhole_merkle.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use {
22
crate::store::{
33
storage::{
4-
AccumulatorState,
54
CompletedAccumulatorState,
65
MessageState,
76
},
@@ -49,23 +48,18 @@ pub async fn store_wormhole_merkle_verified_message(
4948
root: WormholeMerkleRoot,
5049
vaa_bytes: Vec<u8>,
5150
) -> Result<()> {
52-
let mut accumulator_state = store
53-
.storage
54-
.fetch_accumulator_state(root.slot)
55-
.await?
56-
.unwrap_or(AccumulatorState {
57-
slot: root.slot,
58-
accumulator_messages: None,
59-
wormhole_merkle_state: None,
60-
});
61-
62-
accumulator_state.wormhole_merkle_state = Some(WormholeMerkleState {
63-
root,
64-
vaa: vaa_bytes,
65-
});
6651
store
6752
.storage
68-
.store_accumulator_state(accumulator_state)
53+
.update_accumulator_state(
54+
root.slot,
55+
Box::new(|mut state| {
56+
state.wormhole_merkle_state = Some(WormholeMerkleState {
57+
root,
58+
vaa: vaa_bytes,
59+
});
60+
state
61+
}),
62+
)
6963
.await?;
7064
Ok(())
7165
}

hermes/src/store/storage.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,20 @@ pub trait Storage: Send + Sync {
134134
filter: MessageStateFilter,
135135
) -> Result<Vec<MessageState>>;
136136

137+
/// Store the accumulator state. Please note that this call will replace the
138+
/// existing accumulator state for the given state's slot. If you wish to
139+
/// update the accumulator state, use `update_accumulator_state` instead.
137140
async fn store_accumulator_state(&self, state: AccumulatorState) -> Result<()>;
138141
async fn fetch_accumulator_state(&self, slot: Slot) -> Result<Option<AccumulatorState>>;
142+
143+
/// Update the accumulator state inplace using the provided callback. The callback
144+
/// takes the current state and returns the new state. If there is no accumulator
145+
/// state for the given slot, the callback will be called with an empty accumulator state.
146+
async fn update_accumulator_state(
147+
&self,
148+
slot: Slot,
149+
callback: Box<dyn (FnOnce(AccumulatorState) -> AccumulatorState) + Send>,
150+
) -> Result<()>;
139151
}
140152

141153
pub type StorageInstance = Box<dyn Storage>;

0 commit comments

Comments
 (0)