wallet_state -> synced_wallet_state. fix for update_wallet

This commit is contained in:
Daniel Krol 2022-06-12 20:37:18 -04:00
parent d467559dcd
commit 729ec3050d

View file

@ -95,11 +95,6 @@ class WalletSync():
hmac = response.json()['hmac'] hmac = response.json()['hmac']
return wallet_state, hmac, conflict return wallet_state, hmac, conflict
# TODO - We should have:
# * self.last_synced_wallet_state - as described
# * self.current_wallet_state - WalletState(cur_encrypted_wallet(), sequence + 1) - and current_wallet_state
# We don't need it yet but we'd be avoiding the entire point of the syncing system. At least keep it around in this demo.
# TODO - do this correctly. This is a hack example. # TODO - do this correctly. This is a hack example.
def derive_login_password(root_password): def derive_login_password(root_password):
return hashlib.sha256(root_password.encode('utf-8')).hexdigest()[:10] return hashlib.sha256(root_password.encode('utf-8')).hexdigest()[:10]
@ -126,14 +121,14 @@ class Client():
# It's mostly simple, but the _validate_new_wallet_state changes may be worth # It's mostly simple, but the _validate_new_wallet_state changes may be worth
# looking at. # looking at.
def _validate_new_wallet_state(self, new_wallet_state): def _validate_new_wallet_state(self, new_wallet_state):
if self.wallet_state is None: if self.synced_wallet_state is None:
# All of the validations here are in reference to what the device already # All of the validations here are in reference to what the device already
# has. If this device is getting a wallet state for the first time, there # has. If this device is getting a wallet state for the first time, there
# is no basis for comparison. # is no basis for comparison.
return True return True
# Make sure that the new sequence is overall later. # Make sure that the new sequence is overall later.
if new_wallet_state.sequence <= self.wallet_state.sequence: if new_wallet_state.sequence <= self.synced_wallet_state.sequence:
return False return False
return True return True
@ -144,7 +139,7 @@ class Client():
self.auth_token = 'bad token' self.auth_token = 'bad token'
self.wallet_state = None self.synced_wallet_state = None
# TODO - save change to disk in between, associated with account and/or # TODO - save change to disk in between, associated with account and/or
# wallet # wallet
@ -160,8 +155,9 @@ class Client():
# now, it'll end up just merging any un-saved local changes with whatever is # now, it'll end up just merging any un-saved local changes with whatever is
# on the server. # on the server.
def new_wallet_state(self): def new_wallet_state(self):
# camel-cased to ease json interop # Represents what's been synced to the wallet sync server. It starts with
self.wallet_state = WalletState(sequence=0, encrypted_wallet='-') # sequence=0 which means nothing has been synced yet.
self.synced_wallet_state = WalletState(sequence=0, encrypted_wallet='-')
# TODO - actual encryption with encryption_key - or maybe not. # TODO - actual encryption with encryption_key - or maybe not.
self._encrypted_wallet_local_changes = '' self._encrypted_wallet_local_changes = ''
@ -207,28 +203,28 @@ class Client():
print (new_wallet_state, hmac) print (new_wallet_state, hmac)
return return
if self.wallet_state != new_wallet_state and not self._validate_new_wallet_state(new_wallet_state): if self.synced_wallet_state != new_wallet_state and not self._validate_new_wallet_state(new_wallet_state):
print ('Error - new wallet does not validate') print ('Error - new wallet does not validate')
print ('current:', self.wallet_state) print ('current:', self.synced_wallet_state)
print ('got:', new_wallet_state) print ('got:', new_wallet_state)
return return
if self.wallet_state is None: if self.synced_wallet_state is None:
# This is if we're getting a wallet_state for the first time. Initialize # This is if we're getting a wallet_state for the first time. Initialize
# the local changes. # the local changes.
self._encrypted_wallet_local_changes = '' self._encrypted_wallet_local_changes = ''
self.wallet_state = new_wallet_state self.synced_wallet_state = new_wallet_state
print ("Got latest walletState:") print ("Got latest walletState:")
pprint(self.wallet_state) pprint(self.synced_wallet_state)
def update_wallet(self): def update_wallet(self):
# Create a *new* wallet state, indicating that it was last updated by this # Create a *new* wallet state, indicating that it was last updated by this
# device, with the updated sequence, and include our local encrypted wallet changes. # device, with the updated sequence, and include our local encrypted wallet changes.
# Don't set self.wallet_state to this until we know that it's accepted by # Don't set self.synced_wallet_state to this until we know that it's accepted by
# the server. # the server.
if not self.wallet_state: if not self.synced_wallet_state:
print ("No wallet state to post.") print ("No wallet state to post.")
return return
@ -236,7 +232,7 @@ class Client():
submitted_wallet_state = WalletState( submitted_wallet_state = WalletState(
encrypted_wallet=self.cur_encrypted_wallet(), encrypted_wallet=self.cur_encrypted_wallet(),
sequence=self.wallet_state.sequence + 1 sequence=self.synced_wallet_state.sequence + 1
) )
hmac = create_hmac(submitted_wallet_state, hmac_key) hmac = create_hmac(submitted_wallet_state, hmac_key)
@ -247,10 +243,6 @@ class Client():
if not new_wallet_state: if not new_wallet_state:
return return
# If there's not a conflict, we submitted successfully and should reset our previously local changes
if not conflict:
self._encrypted_wallet_local_changes = ''
# TODO - there's some code in common here with the get_wallet function. factor it out. # TODO - there's some code in common here with the get_wallet function. factor it out.
if not check_hmac(new_wallet_state, hmac_key, new_hmac): if not check_hmac(new_wallet_state, hmac_key, new_hmac):
@ -260,28 +252,32 @@ class Client():
if submitted_wallet_state != new_wallet_state and not self._validate_new_wallet_state(new_wallet_state): if submitted_wallet_state != new_wallet_state and not self._validate_new_wallet_state(new_wallet_state):
print ('Error - new wallet does not validate') print ('Error - new wallet does not validate')
print ('current:', self.wallet_state) print ('current:', self.synced_wallet_state)
print ('got:', new_wallet_state) print ('got:', new_wallet_state)
return return
self.wallet_state = new_wallet_state # If there's not a conflict, we submitted successfully and should reset our previously local changes
if not conflict:
self._encrypted_wallet_local_changes = ''
self.synced_wallet_state = new_wallet_state
print ("Got new walletState:") print ("Got new walletState:")
pprint(self.wallet_state) pprint(self.synced_wallet_state)
def change_encrypted_wallet(self): def change_encrypted_wallet(self):
if not self.wallet_state: if not self.synced_wallet_state:
print ("No wallet state, so we can't add to it yet.") print ("No wallet state, so we can't add to it yet.")
return return
self._encrypted_wallet_local_changes += ':' + ''.join(random.choice(string.hexdigits) for x in range(4)) self._encrypted_wallet_local_changes += ':' + ''.join(random.choice(string.hexdigits) for x in range(4))
def cur_encrypted_wallet(self): def cur_encrypted_wallet(self):
if not self.wallet_state: if not self.synced_wallet_state:
print ("No wallet state, so no encrypted wallet.") print ("No wallet state, so no encrypted wallet.")
return return
# The local changes on top of whatever came from the server # The local changes on top of whatever came from the server
# If we pull new changes from server, we "rebase" these on top of it # If we pull new changes from server, we "rebase" these on top of it
# If we push changes, the full "rebased" version gets committed to the server # If we push changes, the full "rebased" version gets committed to the server
return self.wallet_state.encrypted_wallet + self._encrypted_wallet_local_changes return self.synced_wallet_state.encrypted_wallet + self._encrypted_wallet_local_changes