Skip to content

Commit 52e8c4e

Browse files
committed
feat: change clarity connection to depend on backing store interface
1 parent 0cec1cd commit 52e8c4e

File tree

7 files changed

+128
-87
lines changed

7 files changed

+128
-87
lines changed

clarity/src/vm/database/clarity_store.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub trait ClarityBackingStore {
7272
/// used to implement time-shifted evaluation.
7373
/// returns the previous block header hash on success
7474
fn set_block_hash(&mut self, bhh: StacksBlockId) -> Result<StacksBlockId>;
75+
fn get_block_hash(&self) -> StacksBlockId;
7576

7677
/// Is None if `block_height` >= the "currently" under construction Stacks block height.
7778
fn get_block_at_height(&mut self, height: u32) -> Option<StacksBlockId>;
@@ -141,6 +142,15 @@ pub trait ClarityBackingStore {
141142
}
142143
}
143144

145+
pub trait ClarityBackingStoreTransaction: ClarityBackingStore {
146+
fn rollback_block(self: Box<Self>);
147+
fn rollback_unconfirmed(self: Box<Self>) -> Result<()>;
148+
fn commit_to(self: Box<Self>, final_bhh: &StacksBlockId) -> Result<()>;
149+
fn commit_unconfirmed(self: Box<Self>);
150+
fn commit_mined_block(self: Box<Self>, will_move_to: &StacksBlockId) -> Result<()>;
151+
fn seal(&mut self) -> TrieHash;
152+
}
153+
144154
// TODO: Figure out where this belongs
145155
pub fn make_contract_hash_key(contract: &QualifiedContractIdentifier) -> String {
146156
format!("clarity-contract::{contract}")
@@ -202,6 +212,10 @@ impl ClarityBackingStore for NullBackingStore {
202212
panic!("NullBackingStore can't set block hash")
203213
}
204214

215+
fn get_block_hash(&self) -> StacksBlockId {
216+
panic!("NullBackingStore can't get block hash")
217+
}
218+
205219
fn get_data(&mut self, _key: &str) -> Result<Option<String>> {
206220
panic!("NullBackingStore can't retrieve data")
207221
}

clarity/src/vm/database/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ pub use self::clarity_db::{
2020
BurnStateDB, ClarityDatabase, HeadersDB, StoreType, NULL_BURN_STATE_DB, NULL_HEADER_DB,
2121
STORE_CONTRACT_SRC_INTERFACE,
2222
};
23-
pub use self::clarity_store::{ClarityBackingStore, SpecialCaseHandler};
23+
pub use self::clarity_store::{
24+
ClarityBackingStore, ClarityBackingStoreTransaction, SpecialCaseHandler,
25+
};
2426
pub use self::key_value_wrapper::{RollbackWrapper, RollbackWrapperPersistedLog};
2527
#[cfg(feature = "rusqlite")]
2628
pub use self::sqlite::SqliteConnection;

clarity/src/vm/database/sqlite.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ impl ClarityBackingStore for MemoryBackingStore {
316316
Err(RuntimeErrorType::UnknownBlockHeaderHash(BlockHeaderHash(bhh.0)).into())
317317
}
318318

319+
fn get_block_hash(&self) -> StacksBlockId {
320+
panic!("MemoryBackingStore can't get block hash")
321+
}
322+
319323
fn get_data(&mut self, key: &str) -> Result<Option<String>> {
320324
SqliteConnection::get(self.get_side_store(), key)
321325
}

stackslib/src/clarity_cli.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::path::PathBuf;
2020
use std::{fs, io};
2121

2222
use clarity::vm::coverage::CoverageReporter;
23+
use clarity::vm::database::ClarityBackingStoreTransaction;
2324
use lazy_static::lazy_static;
2425
use rand::Rng;
2526
use rusqlite::{Connection, OpenFlags};
@@ -352,6 +353,7 @@ where
352353
let (headers_return, result) = {
353354
let marf_tx = marf_kv.begin(&from, &to);
354355
let (headers_return, marf_return, result) = f(headers_db, marf_tx);
356+
let marf_return: Box<dyn ClarityBackingStoreTransaction> = Box::new(marf_return);
355357
marf_return
356358
.commit_to(&to)
357359
.expect("FATAL: failed to commit block");
@@ -374,6 +376,7 @@ where
374376

375377
let marf_tx = marf_kv.begin(&from, &to);
376378
let (marf_return, result) = f(marf_tx);
379+
let marf_return: Box<dyn ClarityBackingStoreTransaction> = Box::new(marf_return);
377380
marf_return.rollback_block();
378381
result
379382
}
@@ -389,6 +392,7 @@ where
389392

390393
let marf_tx = marf_kv.begin(&from, &to);
391394
let (marf_return, result) = f(marf_tx);
395+
let marf_return: Box<dyn ClarityBackingStoreTransaction> = Box::new(marf_return);
392396
marf_return.rollback_block();
393397
result
394398
}

stackslib/src/clarity_vm/clarity.rs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ pub use clarity::vm::clarity::{ClarityConnection, Error};
2525
use clarity::vm::contexts::{AssetMap, OwnedEnvironment};
2626
use clarity::vm::costs::{CostTracker, ExecutionCost, LimitedCostTracker};
2727
use clarity::vm::database::{
28-
BurnStateDB, ClarityBackingStore, ClarityDatabase, HeadersDB, RollbackWrapper,
29-
RollbackWrapperPersistedLog, STXBalance, NULL_BURN_STATE_DB, NULL_HEADER_DB,
28+
BurnStateDB, ClarityBackingStore, ClarityBackingStoreTransaction, ClarityDatabase, HeadersDB,
29+
RollbackWrapper, RollbackWrapperPersistedLog, STXBalance, NULL_BURN_STATE_DB, NULL_HEADER_DB,
3030
};
3131
use clarity::vm::errors::Error as InterpreterError;
3232
use clarity::vm::events::{STXEventType, STXMintEventData};
@@ -53,7 +53,7 @@ use crate::chainstate::stacks::{
5353
Error as ChainstateError, StacksMicroblockHeader, StacksTransaction, TransactionPayload,
5454
TransactionSmartContract, TransactionVersion,
5555
};
56-
use crate::clarity_vm::database::marf::{MarfedKV, ReadOnlyMarfStore, WritableMarfStore};
56+
use crate::clarity_vm::database::marf::MarfedKV;
5757
use crate::core::{StacksEpoch, StacksEpochId, FIRST_STACKS_BLOCK_ID, GENESIS_EPOCH};
5858
use crate::util_lib::boot::{boot_code_acc, boot_code_addr, boot_code_id, boot_code_tx_auth};
5959
use crate::util_lib::db::Error as DatabaseError;
@@ -101,15 +101,15 @@ pub struct ClarityInstance {
101101
/// issuring event dispatches, before the Clarity database commits.
102102
///
103103
pub struct PreCommitClarityBlock<'a> {
104-
datastore: WritableMarfStore<'a>,
104+
datastore: Box<dyn ClarityBackingStoreTransaction + 'a>,
105105
commit_to: StacksBlockId,
106106
}
107107

108108
///
109109
/// A high-level interface for Clarity VM interactions within a single block.
110110
///
111111
pub struct ClarityBlockConnection<'a, 'b> {
112-
datastore: WritableMarfStore<'a>,
112+
datastore: Box<dyn ClarityBackingStoreTransaction + 'a>,
113113
header_db: &'b dyn HeadersDB,
114114
burn_state_db: &'b dyn BurnStateDB,
115115
cost_track: Option<LimitedCostTracker>,
@@ -160,7 +160,7 @@ impl<'a, 'b> ClarityTransactionConnection<'a, 'b> {
160160
}
161161

162162
pub struct ClarityReadOnlyConnection<'a> {
163-
datastore: ReadOnlyMarfStore<'a>,
163+
datastore: Box<dyn ClarityBackingStore + 'a>,
164164
header_db: &'a dyn HeadersDB,
165165
burn_state_db: &'a dyn BurnStateDB,
166166
epoch: StacksEpochId,
@@ -196,13 +196,13 @@ macro_rules! using {
196196
impl ClarityBlockConnection<'_, '_> {
197197
#[cfg(test)]
198198
pub fn new_test_conn<'a, 'b>(
199-
datastore: WritableMarfStore<'a>,
199+
datastore: super::database::marf::WritableMarfStore<'a>,
200200
header_db: &'b dyn HeadersDB,
201201
burn_state_db: &'b dyn BurnStateDB,
202202
epoch: StacksEpochId,
203203
) -> ClarityBlockConnection<'a, 'b> {
204204
ClarityBlockConnection {
205-
datastore,
205+
datastore: Box::new(datastore),
206206
header_db,
207207
burn_state_db,
208208
cost_track: Some(LimitedCostTracker::new_free()),
@@ -251,7 +251,7 @@ impl ClarityBlockConnection<'_, '_> {
251251
&mut self,
252252
burn_state_db: &dyn BurnStateDB,
253253
) -> Result<StacksEpochId, Error> {
254-
let mut db = self.datastore.as_clarity_db(self.header_db, burn_state_db);
254+
let mut db = ClarityDatabase::new(self.datastore.as_mut(), self.header_db, burn_state_db);
255255
// NOTE: the begin/roll_back shouldn't be necessary with how this gets used in practice,
256256
// but is put here defensively.
257257
db.begin();
@@ -328,7 +328,7 @@ impl ClarityInstance {
328328
};
329329

330330
ClarityBlockConnection {
331-
datastore,
331+
datastore: Box::new(datastore),
332332
header_db,
333333
burn_state_db,
334334
cost_track,
@@ -352,7 +352,7 @@ impl ClarityInstance {
352352
let cost_track = Some(LimitedCostTracker::new_free());
353353

354354
ClarityBlockConnection {
355-
datastore,
355+
datastore: Box::new(datastore),
356356
header_db,
357357
burn_state_db,
358358
cost_track,
@@ -378,7 +378,7 @@ impl ClarityInstance {
378378
let cost_track = Some(LimitedCostTracker::new_free());
379379

380380
let mut conn = ClarityBlockConnection {
381-
datastore: writable,
381+
datastore: Box::new(writable),
382382
header_db,
383383
burn_state_db,
384384
cost_track,
@@ -477,7 +477,7 @@ impl ClarityInstance {
477477
let cost_track = Some(LimitedCostTracker::new_free());
478478

479479
let mut conn = ClarityBlockConnection {
480-
datastore: writable,
480+
datastore: Box::new(writable),
481481
header_db,
482482
burn_state_db,
483483
cost_track,
@@ -559,6 +559,7 @@ impl ClarityInstance {
559559

560560
pub fn drop_unconfirmed_state(&mut self, block: &StacksBlockId) -> Result<(), Error> {
561561
let datastore = self.datastore.begin_unconfirmed(block);
562+
let datastore: Box<dyn ClarityBackingStoreTransaction> = Box::new(datastore);
562563
datastore.rollback_unconfirmed()?;
563564
Ok(())
564565
}
@@ -588,7 +589,7 @@ impl ClarityInstance {
588589
};
589590

590591
ClarityBlockConnection {
591-
datastore,
592+
datastore: Box::new(datastore),
592593
header_db,
593594
burn_state_db,
594595
cost_track,
@@ -628,7 +629,7 @@ impl ClarityInstance {
628629
}?;
629630

630631
Ok(ClarityReadOnlyConnection {
631-
datastore,
632+
datastore: Box::new(datastore),
632633
header_db,
633634
burn_state_db,
634635
epoch,
@@ -677,7 +678,8 @@ impl ClarityConnection for ClarityBlockConnection<'_, '_> {
677678
where
678679
F: FnOnce(ClarityDatabase) -> (R, ClarityDatabase),
679680
{
680-
let mut db = ClarityDatabase::new(&mut self.datastore, self.header_db, self.burn_state_db);
681+
let mut db =
682+
ClarityDatabase::new(self.datastore.as_mut(), self.header_db, self.burn_state_db);
681683
db.begin();
682684
let (result, mut db) = to_do(db);
683685
db.roll_back()
@@ -689,7 +691,7 @@ impl ClarityConnection for ClarityBlockConnection<'_, '_> {
689691
where
690692
F: FnOnce(&mut AnalysisDatabase) -> R,
691693
{
692-
let mut db = AnalysisDatabase::new(&mut self.datastore);
694+
let mut db = AnalysisDatabase::new(self.datastore.as_mut());
693695
db.begin();
694696
let result = to_do(&mut db);
695697
db.roll_back()
@@ -708,9 +710,8 @@ impl ClarityConnection for ClarityReadOnlyConnection<'_> {
708710
where
709711
F: FnOnce(ClarityDatabase) -> (R, ClarityDatabase),
710712
{
711-
let mut db = self
712-
.datastore
713-
.as_clarity_db(self.header_db, self.burn_state_db);
713+
let mut db =
714+
ClarityDatabase::new(self.datastore.as_mut(), self.header_db, self.burn_state_db);
714715
db.begin();
715716
let (result, mut db) = to_do(db);
716717
db.roll_back()
@@ -722,7 +723,7 @@ impl ClarityConnection for ClarityReadOnlyConnection<'_> {
722723
where
723724
F: FnOnce(&mut AnalysisDatabase) -> R,
724725
{
725-
let mut db = self.datastore.as_analysis_db();
726+
let mut db = AnalysisDatabase::new(self.datastore.as_mut());
726727
db.begin();
727728
let result = to_do(&mut db);
728729
db.roll_back()
@@ -773,7 +774,8 @@ impl<'a> ClarityBlockConnection<'a, '_> {
773774
#[cfg(test)]
774775
pub fn commit_block(self) -> LimitedCostTracker {
775776
debug!("Commit Clarity datastore");
776-
self.datastore.test_commit();
777+
let bhh = self.datastore.get_block_hash();
778+
self.datastore.commit_to(&bhh).unwrap();
777779

778780
self.cost_track.unwrap()
779781
}
@@ -1709,7 +1711,7 @@ impl<'a> ClarityBlockConnection<'a, '_> {
17091711

17101712
pub fn start_transaction_processing(&mut self) -> ClarityTransactionConnection<'_, '_> {
17111713
ClarityTransactionConnection::new(
1712-
&mut self.datastore,
1714+
self.datastore.as_mut(),
17131715
self.header_db,
17141716
self.burn_state_db,
17151717
&mut self.cost_track,
@@ -1761,7 +1763,7 @@ impl<'a> ClarityBlockConnection<'a, '_> {
17611763
self.datastore.seal()
17621764
}
17631765

1764-
pub fn destruct(self) -> WritableMarfStore<'a> {
1766+
pub fn destruct(self) -> Box<dyn ClarityBackingStore + 'a> {
17651767
self.datastore
17661768
}
17671769

0 commit comments

Comments
 (0)