From e86b52028425740edc76d4bf83daf891dccbc3b6 Mon Sep 17 00:00:00 2001 From: haammar-ledger Date: Mon, 15 Nov 2021 18:23:28 +0100 Subject: [PATCH] LL-8115 Additional fix for correct handling of change output --- src/families/bitcoin/js-synchronisation.ts | 48 +++++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/families/bitcoin/js-synchronisation.ts b/src/families/bitcoin/js-synchronisation.ts index d8ca22f837..36700e980a 100644 --- a/src/families/bitcoin/js-synchronisation.ts +++ b/src/families/bitcoin/js-synchronisation.ts @@ -129,24 +129,50 @@ const mapTxToOperations = ( const transactionSequenceNumber = (accountInputs.length > 0 && accountInputs[0].sequence) || undefined; - // Change output is the last one + const hasSpentNothing = value.eq(0); + // Change output is always the last one const changeOutputIndex = tx.outputs .map((o) => o.output_index) .reduce((p, c) => (p > c ? p : c)); for (const output of tx.outputs) { if (output.address) { - if (accountAddresses.includes(output.address)) { + if (!accountAddresses.includes(output.address)) { + // The output doesn't belong to this account + if (output.output_index < changeOutputIndex) { + // The output isn't the change output + recipients.push( + syncReplaceAddress + ? syncReplaceAddress(output.address) + : output.address + ); + } + } else { + // The output belongs to this account accountOutputs.push(output); - } else if ( - !changeAddresses.includes(output.address) || - output.output_index !== changeOutputIndex - ) { - recipients.push( - syncReplaceAddress - ? syncReplaceAddress(output.address) - : output.address - ); + + if (!changeAddresses.includes(output.address)) { + // The output isn't a change output of this account + recipients.push( + syncReplaceAddress + ? syncReplaceAddress(output.address) + : output.address + ); + } else { + // The output is a change output of this account, + // we count it as a recipient only in some special cases + if ( + (recipients.length === 0 && + output.output_index >= changeOutputIndex) || + hasSpentNothing + ) { + recipients.push( + syncReplaceAddress + ? syncReplaceAddress(output.address) + : output.address + ); + } + } } } }