Skip to content

Commit 592608a

Browse files
authored
feat: implement NamedBarrier (#12)
* implement NamedBarrier * fix clippy
1 parent fc9a707 commit 592608a

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

src/payload/checkpoint.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<P: Platform> Checkpoint<P> {
114114
/// represents a bundle.
115115
pub fn transactions(&self) -> &[Recovered<types::Transaction<P>>] {
116116
match &self.inner.mutation {
117-
Mutation::Barrier => &[],
117+
Mutation::Barrier | Mutation::NamedBarrier(_) => &[],
118118
Mutation::Executable(result) => result.transactions(),
119119
}
120120
}
@@ -123,7 +123,7 @@ impl<P: Platform> Checkpoint<P> {
123123
/// checkpoint.
124124
pub fn result(&self) -> Option<&ExecutionResult<P>> {
125125
match &self.inner.mutation {
126-
Mutation::Barrier => None,
126+
Mutation::Barrier | Mutation::NamedBarrier(_) => None,
127127
Mutation::Executable(result) => Some(result),
128128
}
129129
}
@@ -132,7 +132,7 @@ impl<P: Platform> Checkpoint<P> {
132132
/// transaction(s) that created this checkpoint.
133133
pub fn state(&self) -> Option<&BundleState> {
134134
match self.inner.mutation {
135-
Mutation::Barrier => None,
135+
Mutation::Barrier | Mutation::NamedBarrier(_) => None,
136136
Mutation::Executable(ref result) => Some(result.state()),
137137
}
138138
}
@@ -142,6 +142,11 @@ impl<P: Platform> Checkpoint<P> {
142142
matches!(self.inner.mutation, Mutation::Barrier)
143143
}
144144

145+
/// Returns true if this checkpoint is a named barrier checkpoint.
146+
pub fn is_named_barrier(&self, name: &str) -> bool {
147+
matches!(self.inner.mutation, Mutation::NamedBarrier(ref barrier_name) if barrier_name == name)
148+
}
149+
145150
/// If this checkpoint is a single transaction, returns a reference to the
146151
/// transaction that created this checkpoint. otherwise returns `None`.
147152
pub fn as_transaction(&self) -> Option<&Recovered<types::Transaction<P>>> {
@@ -207,6 +212,22 @@ impl<P: Platform> Checkpoint<P> {
207212
}),
208213
}
209214
}
215+
216+
/// Creates a new checkpoint on top of the current checkpoint that introduces
217+
/// a named barrier. This new checkpoint will be now considered the new
218+
/// beginning of mutable history.
219+
#[must_use]
220+
pub fn named_barrier(&self, name: impl Into<String>) -> Self {
221+
Self {
222+
inner: Arc::new(CheckpointInner {
223+
block: self.inner.block.clone(),
224+
prev: Some(Arc::clone(&self.inner)),
225+
depth: self.inner.depth + 1,
226+
mutation: Mutation::NamedBarrier(name.into()),
227+
created_at: Instant::now(),
228+
}),
229+
}
230+
}
210231
}
211232

212233
/// Internal API
@@ -249,6 +270,11 @@ enum Mutation<P: Platform> {
249270
/// the previous checkpoint. The executable item can be a single transaction
250271
/// or a bundle of transactions.
251272
Executable(ExecutionResult<P>),
273+
274+
/// A checkpoint that was created by applying a named barrier on top of the
275+
/// previous checkpoint. The named barrier is used to indicate that any prior
276+
/// checkpoints are immutable and should not be discarded or reordered.
277+
NamedBarrier(String),
252278
}
253279

254280
struct CheckpointInner<P: Platform> {
@@ -445,7 +471,15 @@ impl<P: Platform> Display for Checkpoint<P> {
445471

446472
// this is a barrier checkpoint, which has no transactions
447473
// applied to it.
448-
return write!(f, "[{}] barrier", self.depth());
474+
return match &self.inner.mutation {
475+
Mutation::Barrier => write!(f, "[{}] barrier", self.depth()),
476+
Mutation::NamedBarrier(name) => {
477+
write!(f, "[{}] barrier '{}'", self.depth(), name)
478+
}
479+
Mutation::Executable(_) => {
480+
unreachable!("Executable variant handled above")
481+
}
482+
};
449483
};
450484

451485
match exec_result.source() {

src/test_utils/step.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ impl<P: PlatformWithRpcTypes + TestNodeFactory<P>> OneStep<P> {
191191
self
192192
}
193193

194+
/// Adds a named barrier to the input payload of the step at the current
195+
/// position.
196+
#[must_use]
197+
pub fn with_payload_named_barrier(mut self, name: impl Into<String>) -> Self {
198+
self
199+
.payload_input
200+
.push(InputPayloadItemFn::NamedBarrier(name.into()));
201+
self
202+
}
203+
194204
/// Adds a new transaction to the mempool and makes it available to the step.
195205
/// Here we don't need to manage nonces, as the mempool will report the
196206
/// pending transactions for the signer and nonces will be set automatically.
@@ -224,6 +234,9 @@ impl<P: PlatformWithRpcTypes + TestNodeFactory<P>> OneStep<P> {
224234
.map(|input| -> eyre::Result<InputPayloadItem<P>> {
225235
Ok(match input {
226236
InputPayloadItemFn::Barrier => InputPayloadItem::Barrier,
237+
InputPayloadItemFn::NamedBarrier(name) => {
238+
InputPayloadItem::NamedBarrier(name)
239+
}
227240
InputPayloadItemFn::Tx(mut builder) => InputPayloadItem::Tx(
228241
builder(
229242
local_node
@@ -298,6 +311,7 @@ impl<P: PlatformWithRpcTypes> Step<P> for PopulatePayload<P> {
298311
while let Ok(input) = self.receiver.lock().await.try_recv() {
299312
payload = match input {
300313
InputPayloadItem::Barrier => payload.barrier(),
314+
InputPayloadItem::NamedBarrier(name) => payload.named_barrier(name),
301315
InputPayloadItem::Tx(tx) => {
302316
payload.apply(tx).expect("Failed to apply transaction")
303317
}
@@ -381,12 +395,14 @@ impl<P: Platform> Step<P> for RecordBreakAndFail<P> {
381395

382396
enum InputPayloadItemFn<P: PlatformWithRpcTypes> {
383397
Barrier,
398+
NamedBarrier(String),
384399
Tx(BoxedTxBuilderFn<P>),
385400
Bundle(types::Bundle<P>),
386401
}
387402

388403
enum InputPayloadItem<P: PlatformWithRpcTypes> {
389404
Barrier,
405+
NamedBarrier(String),
390406
Tx(types::TxEnvelope<P>),
391407
Bundle(types::Bundle<P>),
392408
}

0 commit comments

Comments
 (0)