Skip to content

Commit 65b8ddc

Browse files
committed
[DB] Specialize CScopedDBTransaction for evo database
>>> backports dash@5b4fe43c2577f3f39fd174c84a8c23c99646903d This has the wanted side effect of proper locking of "cs" inside CommitCurTransaction and RollbackCurTransaction, which was not easily possible to implement in the generic version. This fixes some rare crashes.
1 parent 34a7541 commit 65b8ddc

File tree

3 files changed

+61
-49
lines changed

3 files changed

+61
-49
lines changed

src/dbwrapper.h

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -498,49 +498,4 @@ class CDBTransaction {
498498
}
499499
};
500500

501-
template<typename Parent, typename CommitTarget>
502-
class CScopedDBTransaction {
503-
public:
504-
typedef CDBTransaction<Parent, CommitTarget> Transaction;
505-
506-
private:
507-
Transaction &dbTransaction;
508-
std::function<void ()> commitHandler;
509-
std::function<void ()> rollbackHandler;
510-
bool didCommitOrRollback{};
511-
512-
public:
513-
explicit CScopedDBTransaction(Transaction &dbTx) : dbTransaction(dbTx) {}
514-
~CScopedDBTransaction() {
515-
if (!didCommitOrRollback)
516-
Rollback();
517-
}
518-
void Commit() {
519-
assert(!didCommitOrRollback);
520-
didCommitOrRollback = true;
521-
dbTransaction.Commit();
522-
if (commitHandler)
523-
commitHandler();
524-
}
525-
void Rollback() {
526-
assert(!didCommitOrRollback);
527-
didCommitOrRollback = true;
528-
dbTransaction.Clear();
529-
if (rollbackHandler)
530-
rollbackHandler();
531-
}
532-
533-
static std::unique_ptr<CScopedDBTransaction<Parent, CommitTarget>> Begin(Transaction &dbTx) {
534-
assert(dbTx.IsClean());
535-
return std::make_unique<CScopedDBTransaction<Parent, CommitTarget>>(dbTx);
536-
}
537-
538-
void SetCommitHandler(const std::function<void ()> &h) {
539-
commitHandler = h;
540-
}
541-
void SetRollbackHandler(const std::function<void ()> &h) {
542-
rollbackHandler = h;
543-
}
544-
};
545-
546501
#endif // BITCOIN_DBWRAPPER_H

src/evo/evodb.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,31 @@
77

88
std::unique_ptr<CEvoDB> evoDb;
99

10+
CEvoDBScopedCommitter::CEvoDBScopedCommitter(CEvoDB &_evoDB) :
11+
evoDB(_evoDB)
12+
{
13+
}
14+
15+
CEvoDBScopedCommitter::~CEvoDBScopedCommitter()
16+
{
17+
if (!didCommitOrRollback)
18+
Rollback();
19+
}
20+
21+
void CEvoDBScopedCommitter::Commit()
22+
{
23+
assert(!didCommitOrRollback);
24+
didCommitOrRollback = true;
25+
evoDB.CommitCurTransaction();
26+
}
27+
28+
void CEvoDBScopedCommitter::Rollback()
29+
{
30+
assert(!didCommitOrRollback);
31+
didCommitOrRollback = true;
32+
evoDB.RollbackCurTransaction();
33+
}
34+
1035
CEvoDB::CEvoDB(size_t nCacheSize, bool fMemory, bool fWipe) :
1136
db(fMemory ? "" : (GetDataDir() / "evodb"), nCacheSize, fMemory, fWipe),
1237
rootBatch(),
@@ -15,6 +40,18 @@ CEvoDB::CEvoDB(size_t nCacheSize, bool fMemory, bool fWipe) :
1540
{
1641
}
1742

43+
void CEvoDB::CommitCurTransaction()
44+
{
45+
LOCK(cs);
46+
curDBTransaction.Commit();
47+
}
48+
49+
void CEvoDB::RollbackCurTransaction()
50+
{
51+
LOCK(cs);
52+
curDBTransaction.Clear();
53+
}
54+
1855
bool CEvoDB::CommitRootTransaction()
1956
{
2057
assert(curDBTransaction.IsClean());

src/evo/evodb.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@
1212

1313
static const std::string EVODB_BEST_BLOCK = "b_b";
1414

15+
class CEvoDB;
16+
17+
class CEvoDBScopedCommitter
18+
{
19+
private:
20+
CEvoDB& evoDB;
21+
bool didCommitOrRollback{false};
22+
23+
public:
24+
explicit CEvoDBScopedCommitter(CEvoDB& _evoDB);
25+
~CEvoDBScopedCommitter();
26+
27+
void Commit();
28+
void Rollback();
29+
};
30+
1531
class CEvoDB
1632
{
1733
private:
@@ -20,7 +36,6 @@ class CEvoDB
2036

2137
typedef CDBTransaction<CDBWrapper, CDBBatch> RootTransaction;
2238
typedef CDBTransaction<RootTransaction, RootTransaction> CurTransaction;
23-
typedef CScopedDBTransaction<RootTransaction, RootTransaction> ScopedTransaction;
2439

2540
CDBBatch rootBatch;
2641
RootTransaction rootDBTransaction;
@@ -29,11 +44,10 @@ class CEvoDB
2944
public:
3045
explicit CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
3146

32-
std::unique_ptr<ScopedTransaction> BeginTransaction()
47+
std::unique_ptr<CEvoDBScopedCommitter> BeginTransaction()
3348
{
3449
LOCK(cs);
35-
auto t = ScopedTransaction::Begin(curDBTransaction);
36-
return t;
50+
return std::make_unique<CEvoDBScopedCommitter>(*this);
3751
}
3852

3953
template<typename K, typename V>
@@ -73,6 +87,12 @@ class CEvoDB
7387

7488
bool VerifyBestBlock(const uint256& hash);
7589
void WriteBestBlock(const uint256& hash);
90+
91+
private:
92+
// only CEvoDBScopedCommitter is allowed to invoke these
93+
friend class CEvoDBScopedCommitter;
94+
void CommitCurTransaction();
95+
void RollbackCurTransaction();
7696
};
7797

7898
extern std::unique_ptr<CEvoDB> evoDb;

0 commit comments

Comments
 (0)