more robust synchronization method
This commit is contained in:
parent
c3dfeec7e7
commit
2f6d919afc
|
@ -52,6 +52,7 @@ class Wallet:
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
self.electrum_version = ELECTRUM_VERSION
|
self.electrum_version = ELECTRUM_VERSION
|
||||||
|
self.gap_limit_for_change = 3 # constant
|
||||||
|
|
||||||
# saved fields
|
# saved fields
|
||||||
self.seed_version = config.get('seed_version', SEED_VERSION)
|
self.seed_version = config.get('seed_version', SEED_VERSION)
|
||||||
|
@ -348,36 +349,45 @@ class Wallet:
|
||||||
return nmax + 1
|
return nmax + 1
|
||||||
|
|
||||||
|
|
||||||
|
def address_is_old(self, address):
|
||||||
|
age = -1
|
||||||
|
h = self.history.get(address, [])
|
||||||
|
if h == ['*']:
|
||||||
|
return True
|
||||||
|
for tx_hash, tx_height in h:
|
||||||
|
if tx_height == 0:
|
||||||
|
tx_age = 0
|
||||||
|
else:
|
||||||
|
tx_age = self.verifier.height - tx_height + 1
|
||||||
|
if tx_age > age:
|
||||||
|
age = tx_age
|
||||||
|
return age > 2
|
||||||
|
|
||||||
|
|
||||||
|
def synchronize_sequence(self, addresses, n, for_change):
|
||||||
|
new_addresses = []
|
||||||
|
while True:
|
||||||
|
if len(self.addresses) < n:
|
||||||
|
new_addresses.append( self.create_new_address(for_change) )
|
||||||
|
continue
|
||||||
|
if map( lambda a: self.address_is_old(a), addresses[-n:] ) == n*[False]:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
new_addresses.append( self.create_new_address(for_change) )
|
||||||
|
return new_addresses
|
||||||
|
|
||||||
|
|
||||||
def synchronize(self):
|
def synchronize(self):
|
||||||
if not self.master_public_key:
|
if not self.master_public_key:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
new_addresses = []
|
new_addresses = []
|
||||||
while True:
|
new_addresses += self.synchronize_sequence(self.addresses, self.gap_limit, False)
|
||||||
if self.change_addresses == []:
|
new_addresses += self.synchronize_sequence(self.change_addresses, self.gap_limit_for_change, True)
|
||||||
new_addresses.append( self.create_new_address(True) )
|
|
||||||
continue
|
|
||||||
a = self.change_addresses[-1]
|
|
||||||
if self.history.get(a):
|
|
||||||
new_addresses.append( self.create_new_address(True) )
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
n = self.gap_limit
|
|
||||||
while True:
|
|
||||||
if len(self.addresses) < n:
|
|
||||||
new_addresses.append( self.create_new_address(False) )
|
|
||||||
continue
|
|
||||||
if map( lambda a: self.history.get(a, []), self.addresses[-n:] ) == n*[[]]:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
new_addresses.append( self.create_new_address(False) )
|
|
||||||
|
|
||||||
return new_addresses
|
return new_addresses
|
||||||
|
|
||||||
|
|
||||||
def is_found(self):
|
def is_found(self):
|
||||||
return (len(self.change_addresses) > 1 ) or ( len(self.addresses) > self.gap_limit )
|
return (len(self.change_addresses) > self.gap_limit_for_change ) or ( len(self.addresses) > self.gap_limit )
|
||||||
|
|
||||||
def fill_addressbook(self):
|
def fill_addressbook(self):
|
||||||
for tx_hash, tx in self.transactions.items():
|
for tx_hash, tx in self.transactions.items():
|
||||||
|
@ -609,7 +619,7 @@ class Wallet:
|
||||||
if change_amount != 0:
|
if change_amount != 0:
|
||||||
# normally, the update thread should ensure that the last change address is unused
|
# normally, the update thread should ensure that the last change address is unused
|
||||||
if not change_addr:
|
if not change_addr:
|
||||||
change_addr = self.change_addresses[-1]
|
change_addr = self.change_addresses[-self.gap_limit_for_change]
|
||||||
# Insert the change output at a random position in the outputs
|
# Insert the change output at a random position in the outputs
|
||||||
posn = random.randint(0, len(outputs))
|
posn = random.randint(0, len(outputs))
|
||||||
outputs[posn:posn] = [( change_addr, change_amount)]
|
outputs[posn:posn] = [( change_addr, change_amount)]
|
||||||
|
|
Loading…
Reference in New Issue