@@ -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
254280struct 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 ( ) {
0 commit comments