electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 2f6d919afc2c3f3b1f14d49f96430716825690d5
parent c3dfeec7e7cb7ce760fe2e76e4a01f32593d4b33
Author: thomasv <thomasv@gitorious>
Date:   Tue, 29 Jan 2013 14:53:13 +0100

more robust synchronization method

Diffstat:
Mlib/wallet.py | 48+++++++++++++++++++++++++++++-------------------
1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/lib/wallet.py b/lib/wallet.py @@ -52,6 +52,7 @@ class Wallet: self.config = config self.electrum_version = ELECTRUM_VERSION + self.gap_limit_for_change = 3 # constant # saved fields self.seed_version = config.get('seed_version', SEED_VERSION) @@ -348,36 +349,45 @@ class Wallet: return nmax + 1 - def synchronize(self): - if not self.master_public_key: - return [] + 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 - new_addresses = [] - while True: - if self.change_addresses == []: - 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 + def synchronize_sequence(self, addresses, n, for_change): + new_addresses = [] while True: if len(self.addresses) < n: - new_addresses.append( self.create_new_address(False) ) + new_addresses.append( self.create_new_address(for_change) ) continue - if map( lambda a: self.history.get(a, []), self.addresses[-n:] ) == n*[[]]: + if map( lambda a: self.address_is_old(a), addresses[-n:] ) == n*[False]: break else: - new_addresses.append( self.create_new_address(False) ) + new_addresses.append( self.create_new_address(for_change) ) + return new_addresses + + def synchronize(self): + if not self.master_public_key: + return [] + new_addresses = [] + new_addresses += self.synchronize_sequence(self.addresses, self.gap_limit, False) + new_addresses += self.synchronize_sequence(self.change_addresses, self.gap_limit_for_change, True) return new_addresses 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): for tx_hash, tx in self.transactions.items(): @@ -609,7 +619,7 @@ class Wallet: if change_amount != 0: # normally, the update thread should ensure that the last change address is unused 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 posn = random.randint(0, len(outputs)) outputs[posn:posn] = [( change_addr, change_amount)]