@ -59,12 +59,12 @@ class JsonDB(Logger):
self . data = { }
self . _modified = False
self . manual_upgrades = manual_upgrades
self . _called_load_transaction s = False
self . _called_after_upgrade_task s = False
if raw : # loading existing db
self . load_data ( raw )
else : # creating new db
self . put ( ' seed_version ' , FINAL_SEED_VERSION )
self . load_transaction s( )
self . _after_upgrade_task s( )
def set_modified ( self , b ) :
with self . lock :
@ -108,12 +108,6 @@ class JsonDB(Logger):
self . data [ key ] = copy . deepcopy ( value )
return True
elif key in self . data :
# clear current contents in case of references
cur_val = self . data [ key ]
clear_method = getattr ( cur_val , " clear " , None )
if callable ( clear_method ) :
clear_method ( )
# pop from dict to delete key
self . data . pop ( key )
return True
return False
@ -149,9 +143,9 @@ class JsonDB(Logger):
if not self . manual_upgrades and self . requires_split ( ) :
raise WalletFileException ( " This wallet has multiple accounts and must be split " )
self . load_transactions ( )
if not self . manual_upgrades and self . requires_upgrade ( ) :
if not self . requires_upgrade ( ) :
self . _after_upgrade_tasks ( )
el if not self . manual_upgrades :
self . upgrade ( )
def requires_split ( self ) :
@ -204,11 +198,9 @@ class JsonDB(Logger):
@profiler
def upgrade ( self ) :
self . logger . info ( ' upgrading wallet format ' )
if not self . _called_load_transactions :
# note: not sure if this is how we should go about this...
# alternatively, we could make sure load_transactions is always called after upgrade
# still, we need strict ordering between the two.
raise Exception ( " ' load_transactions ' must be called before ' upgrade ' " )
if self . _called_after_upgrade_tasks :
# we need strict ordering between upgrade() and after_upgrade_tasks()
raise Exception ( " ' after_upgrade_tasks ' must NOT be called before ' upgrade ' " )
self . _convert_imported ( )
self . _convert_wallet_type ( )
self . _convert_account ( )
@ -220,6 +212,12 @@ class JsonDB(Logger):
self . _convert_version_18 ( )
self . put ( ' seed_version ' , FINAL_SEED_VERSION ) # just to be sure
self . _after_upgrade_tasks ( )
def _after_upgrade_tasks ( self ) :
self . _called_after_upgrade_tasks = True
self . _load_transactions ( )
def _convert_wallet_type ( self ) :
if not self . _is_upgrade_method_needed ( 0 , 13 ) :
return
@ -415,9 +413,10 @@ class JsonDB(Logger):
self . put ( ' pruned_txo ' , None )
transactions = self . get ( ' transactions ' , { } ) # txid -> Transaction
transactions = self . get ( ' transactions ' , { } ) # txid -> raw_tx
spent_outpoints = defaultdict ( dict )
for txid , tx in transactions . items ( ) :
for txid , raw_tx in transactions . items ( ) :
tx = Transaction ( raw_tx )
for txin in tx . inputs ( ) :
if txin [ ' type ' ] == ' coinbase ' :
continue
@ -475,6 +474,7 @@ class JsonDB(Logger):
self . put ( ' accounts ' , None )
def _is_upgrade_method_needed ( self , min_version , max_version ) :
assert min_version < = max_version
cur_version = self . get_seed_version ( )
if cur_version > max_version :
return False
@ -673,6 +673,8 @@ class JsonDB(Logger):
@locked
def get_data_ref ( self , name ) :
# Warning: interacts un-intuitively with 'put': certain parts
# of 'data' will have pointers saved as separate variables.
if name not in self . data :
self . data [ name ] = { }
return self . data [ name ]
@ -745,8 +747,7 @@ class JsonDB(Logger):
self . _addr_to_addr_index [ addr ] = ( True , i )
@profiler
def load_transactions ( self ) :
self . _called_load_transactions = True
def _load_transactions ( self ) :
# references in self.data
self . txi = self . get_data_ref ( ' txi ' ) # txid -> address -> list of (prev_outpoint, value)
self . txo = self . get_data_ref ( ' txo ' ) # txid -> address -> list of (output_index, value, is_coinbase)