@ -23,7 +23,23 @@ public:
dbwrapper_error ( const std : : string & msg ) : std : : runtime_error ( msg ) { }
} ;
void HandleError ( const leveldb : : Status & status ) throw ( dbwrapper_error ) ;
class CDBWrapper ;
/** These should be considered an implementation detail of the specific database.
*/
namespace dbwrapper_private {
/** Handle database error by throwing dbwrapper_error exception.
*/
void HandleError ( const leveldb : : Status & status ) ;
/** Work around circular dependency, as well as for testing in dbwrapper_tests.
* Database obfuscation should be considered an implementation detail of the
* specific database .
*/
const std : : vector < unsigned char > & GetObfuscateKey ( const CDBWrapper & w ) ;
} ;
/** Batch of changes queued to be written to a CDBWrapper */
class CDBBatch
@ -31,14 +47,14 @@ class CDBBatch
friend class CDBWrapper ;
private :
const CDBWrapper & parent ;
leveldb : : WriteBatch batch ;
const std : : vector < unsigned char > * obfuscate_key ;
public :
/**
* @ param [ in ] obfuscate_key If passed , XOR data with this key .
* @ param [ in ] parent CDBWrapper that this batch is to be submitted to
*/
CDBBatch ( const std: : vector < unsigned char > * obfuscate_key ) : obfuscate_key ( obfuscate_key ) { } ;
CDBBatch ( const CDBWrapper & parent ) : parent ( parent ) { } ;
template < typename K , typename V >
void Write ( const K & key , const V & value )
@ -51,7 +67,7 @@ public:
CDataStream ssValue ( SER_DISK , CLIENT_VERSION ) ;
ssValue . reserve ( ssValue . GetSerializeSize ( value ) ) ;
ssValue < < value ;
ssValue . Xor ( * obfuscate_key ) ;
ssValue . Xor ( dbwrapper_private : : GetObfuscateKey ( parent ) ) ;
leveldb : : Slice slValue ( & ssValue [ 0 ] , ssValue . size ( ) ) ;
batch . Put ( slKey , slValue ) ;
@ -72,17 +88,17 @@ public:
class CDBIterator
{
private :
const CDBWrapper & parent ;
leveldb : : Iterator * piter ;
const std : : vector < unsigned char > * obfuscate_key ;
public :
/**
* @ param [ in ] parent Parent CDBWrapper instance .
* @ param [ in ] piterIn The original leveldb iterator .
* @ param [ in ] obfuscate_key If passed , XOR data with this key .
*/
CDBIterator ( leveldb : : Iterator * piterIn , const std : : vector < unsigned char > * obfuscate_key ) :
p iter( piterIn ) , obfuscate_key ( obfuscate_key ) { } ;
CDBIterator ( const CDBWrapper & parent , leveldb : : Iterator * piterIn ) :
p arent( parent ) , piter ( piterIn ) { } ;
~ CDBIterator ( ) ;
bool Valid ( ) ;
@ -118,7 +134,7 @@ public:
leveldb : : Slice slValue = piter - > value ( ) ;
try {
CDataStream ssValue ( slValue . data ( ) , slValue . data ( ) + slValue . size ( ) , SER_DISK , CLIENT_VERSION ) ;
ssValue . Xor ( * obfuscate_key ) ;
ssValue . Xor ( dbwrapper_private : : GetObfuscateKey ( parent ) ) ;
ssValue > > value ;
} catch ( const std : : exception & ) {
return false ;
@ -134,6 +150,7 @@ public:
class CDBWrapper
{
friend const std : : vector < unsigned char > & dbwrapper_private : : GetObfuscateKey ( const CDBWrapper & w ) ;
private :
//! custom environment this database is using (may be NULL in case of default environment)
leveldb : : Env * penv ;
@ -180,7 +197,7 @@ public:
~ CDBWrapper ( ) ;
template < typename K , typename V >
bool Read ( const K & key , V & value ) const throw ( dbwrapper_error )
bool Read ( const K & key , V & value ) const
{
CDataStream ssKey ( SER_DISK , CLIENT_VERSION ) ;
ssKey . reserve ( ssKey . GetSerializeSize ( key ) ) ;
@ -193,7 +210,7 @@ public:
if ( status . IsNotFound ( ) )
return false ;
LogPrintf ( " LevelDB read failure: %s \n " , status . ToString ( ) ) ;
HandleError ( status ) ;
dbwrapper_private : : HandleError ( status ) ;
}
try {
CDataStream ssValue ( strValue . data ( ) , strValue . data ( ) + strValue . size ( ) , SER_DISK , CLIENT_VERSION ) ;
@ -206,15 +223,15 @@ public:
}
template < typename K , typename V >
bool Write ( const K & key , const V & value , bool fSync = false ) throw ( dbwrapper_error )
bool Write ( const K & key , const V & value , bool fSync = false )
{
CDBBatch batch ( &obfuscate_key ) ;
CDBBatch batch ( *this ) ;
batch . Write ( key , value ) ;
return WriteBatch ( batch , fSync ) ;
}
template < typename K >
bool Exists ( const K & key ) const throw ( dbwrapper_error )
bool Exists ( const K & key ) const
{
CDataStream ssKey ( SER_DISK , CLIENT_VERSION ) ;
ssKey . reserve ( ssKey . GetSerializeSize ( key ) ) ;
@ -227,20 +244,20 @@ public:
if ( status . IsNotFound ( ) )
return false ;
LogPrintf ( " LevelDB read failure: %s \n " , status . ToString ( ) ) ;
HandleError ( status ) ;
dbwrapper_private : : HandleError ( status ) ;
}
return true ;
}
template < typename K >
bool Erase ( const K & key , bool fSync = false ) throw ( dbwrapper_error )
bool Erase ( const K & key , bool fSync = false )
{
CDBBatch batch ( &obfuscate_key ) ;
CDBBatch batch ( *this ) ;
batch . Erase ( key ) ;
return WriteBatch ( batch , fSync ) ;
}
bool WriteBatch ( CDBBatch & batch , bool fSync = false ) throw ( dbwrapper_error ) ;
bool WriteBatch ( CDBBatch & batch , bool fSync = false ) ;
// not available for LevelDB; provide for compatibility with BDB
bool Flush ( )
@ -248,32 +265,21 @@ public:
return true ;
}
bool Sync ( ) throw ( dbwrapper_error )
bool Sync ( )
{
CDBBatch batch ( &obfuscate_key ) ;
CDBBatch batch ( *this ) ;
return WriteBatch ( batch , true ) ;
}
CDBIterator * NewIterator ( )
{
return new CDBIterator ( pdb - > NewIterator ( iteroptions ) , & obfuscate_key ) ;
return new CDBIterator ( * this , pdb - > NewIterator ( iteroptions ) ) ;
}
/**
* Return true if the database managed by this class contains no entries .
*/
bool IsEmpty ( ) ;
/**
* Accessor for obfuscate_key .
*/
const std : : vector < unsigned char > & GetObfuscateKey ( ) const ;
/**
* Return the obfuscate_key as a hex - formatted string .
*/
std : : string GetObfuscateKeyHex ( ) const ;
} ;
# endif // BITCOIN_DBWRAPPER_H