Skip to content

Commit

Permalink
psbt: check if all inputs are already signed
Browse files Browse the repository at this point in the history
  • Loading branch information
stepansnigirev committed Nov 16, 2022
1 parent 5b8ca01 commit 9deaebb
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/apps/wallets/liquid/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ def preprocess_psbt(self, stream, fout):
# compress = True flag will make sure large fields won't be loaded to RAM
psbtv = self.PSBTViewClass.view(stream, compress=True)

signed_inputs = self.check_signed_inputs(psbtv)

# Start with global fields of PSBT

# On Liquid we check if txseed is provided (for deterministic blinding)
Expand All @@ -273,6 +275,7 @@ def preprocess_psbt(self, stream, fout):
"inputs": [{} for i in range(psbtv.num_inputs)],
"outputs": [{} for i in range(psbtv.num_outputs)],
"issuance": False, "reissuance": False,
"signed_inputs": signed_inputs,
}

fingerprint = self.keystore.fingerprint
Expand Down
32 changes: 32 additions & 0 deletions src/apps/wallets/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,19 @@ async def confirm_transaction(self, wallets, meta, show_screen):
if sighash == False:
return

if meta.get("signed_inputs", 0) == len(meta.get("inputs", [])):
scr = Prompt(
"Warning!",
"\nThe transaction is already signed!\n\n\n"
"All inputs in this transaction\n"
"contain final witness or scriptsig.\n\n\n"
"There is no need to add any extra signatures.\n\n\n"
"Proceed anyway?",
)
proceed = await show_screen(scr)
if not proceed:
return

# ask if we want to continue with unknown wallets
if not await self.confirm_wallets(wallets, show_screen):
return
Expand Down Expand Up @@ -579,6 +592,21 @@ def fill_zero_fingerprint(self, scope):
if self.keystore.get_xpub(scope.bip32_derivations[pub].derivation).key == pub:
scope.bip32_derivations[pub].fingerprint = self.keystore.fingerprint

def check_signed_inputs(self, psbtv):
"""Goes through all input scopes and checks if they are already signed"""
signed_inputs = 0
for i in range(psbtv.num_inputs):
psbtv.seek_to_scope(i)
off = psbtv.seek_to_value(b"\x07", from_current=True) # final scriptsig
if off is not None:
signed_inputs += 1
continue
psbtv.seek_to_scope(i)
off = psbtv.seek_to_value(b"\x08", from_current=True) # final scriptwitness
if off is not None:
signed_inputs += 1
continue
return signed_inputs

def preprocess_psbt(self, stream, fout):
"""
Expand All @@ -592,6 +620,9 @@ def preprocess_psbt(self, stream, fout):
# compress = True flag will make sure large fields won't be loaded to RAM
psbtv = self.PSBTViewClass.view(stream, compress=True)

# check if inputs are already signed
signed_inputs = self.check_signed_inputs(psbtv)

# Write global scope first
psbtv.stream.seek(psbtv.offset)
res = read_write(psbtv.stream, fout, psbtv.first_scope-psbtv.offset)
Expand All @@ -606,6 +637,7 @@ def preprocess_psbt(self, stream, fout):
"inputs": [{} for i in range(psbtv.num_inputs)],
"outputs": [{} for i in range(psbtv.num_outputs)],
"default_asset": "BTC" if self.network == "main" else "tBTC",
"signed_inputs": signed_inputs,
}

fingerprint = self.keystore.fingerprint
Expand Down

0 comments on commit 9deaebb

Please sign in to comment.