Skip to content

Commit

Permalink
Merge pull request #217 from liquality/btc-find-function-fixes
Browse files Browse the repository at this point in the history
Fix find functions
  • Loading branch information
monokh committed Sep 24, 2019
2 parents 86c3a89 + aaa8abf commit cb0adba
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 33 deletions.
40 changes: 31 additions & 9 deletions packages/bitcoin-swap-provider/lib/BitcoinSwapProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,32 @@ export default class BitcoinSwapProvider extends Provider {
return this.getMethod('sendRawTransaction')(tx.toHex())
}

doesTransactionMatchSwapParams (transaction, value, recipientAddress, refundAddress, secretHash, expiration) {
getInputScriptFromTransaction (tx) {
const vin = tx._raw.vin[0]
if (!vin.scriptSig) return null

const inputScript = vin.txinwitness ? vin.txinwitness
: bitcoin.script.decompile(Buffer.from(vin.scriptSig.hex, 'hex'))
.map(b => Buffer.isBuffer(b) ? b.toString('hex') : b)
return inputScript
}

doesTransactionMatchRedeem (initiationTxHash, tx, address, isRefund) {
if (tx._raw.vin[0].txid !== initiationTxHash) return false
const inputScript = this.getInputScriptFromTransaction(tx)
if (!inputScript) return false
if (isRefund) {
if (inputScript.length !== 4) return false
} else {
if (inputScript.length !== 5) return false
}
const vout = tx._raw.vout.find(vout => vout.scriptPubKey.addresses && vout.scriptPubKey.addresses.includes(address))
if (!vout) return false

return true
}

doesTransactionMatchInitiation (transaction, value, recipientAddress, refundAddress, secretHash, expiration) {
const swapOutput = this.getSwapOutput(recipientAddress, refundAddress, secretHash, expiration)
const swapPaymentVariants = this.getSwapPaymentVariants(swapOutput)
const vout = transaction._raw.vout.find(vout =>
Expand All @@ -201,7 +226,7 @@ export default class BitcoinSwapProvider extends Provider {

async verifyInitiateSwapTransaction (initiationTxHash, value, recipientAddress, refundAddress, secretHash, expiration) {
const initiationTransaction = await this.getMethod('getTransactionByHash')(initiationTxHash)
return this.doesTransactionMatchSwapParams(initiationTransaction, value, recipientAddress, refundAddress, secretHash, expiration)
return this.doesTransactionMatchInitiation(initiationTransaction, value, recipientAddress, refundAddress, secretHash, expiration)
}

async findSwapTransaction (recipientAddress, refundAddress, secretHash, expiration, startBlock, predicate) {
Expand All @@ -228,13 +253,13 @@ export default class BitcoinSwapProvider extends Provider {

async findInitiateSwapTransaction (value, recipientAddress, refundAddress, secretHash, expiration, startBlock) {
return this.findSwapTransaction(recipientAddress, refundAddress, secretHash, expiration, startBlock,
tx => this.doesTransactionMatchSwapParams(tx, value, recipientAddress, refundAddress, secretHash, expiration)
tx => this.doesTransactionMatchInitiation(tx, value, recipientAddress, refundAddress, secretHash, expiration)
)
}

async findClaimSwapTransaction (initiationTxHash, recipientAddress, refundAddress, secretHash, expiration, startBlock) {
const claimSwapTransaction = await this.findSwapTransaction(recipientAddress, refundAddress, secretHash, expiration, startBlock,
tx => tx._raw.vout.find(vout => vout.scriptPubKey.addresses && vout.scriptPubKey.addresses.includes(recipientAddress))
tx => this.doesTransactionMatchRedeem(initiationTxHash, tx, recipientAddress, false)
)

return {
Expand All @@ -245,17 +270,14 @@ export default class BitcoinSwapProvider extends Provider {

async findRefundSwapTransaction (initiationTxHash, recipientAddress, refundAddress, secretHash, expiration, startBlock) {
const refundSwapTransaction = await this.findSwapTransaction(recipientAddress, refundAddress, secretHash, expiration, startBlock,
tx => tx._raw.vout.find(vout => vout.scriptPubKey.addresses && vout.scriptPubKey.addresses.includes(refundAddress))
tx => this.doesTransactionMatchRedeem(initiationTxHash, tx, refundAddress, true)
)
return refundSwapTransaction
}

async getSwapSecret (claimTxHash) {
const claimTx = await this.getMethod('getTransactionByHash')(claimTxHash)
const vin = claimTx._raw.vin[0]
const inputScript = vin.txinwitness ? vin.txinwitness
: bitcoin.script.decompile(Buffer.from(vin.scriptSig.hex, 'hex'))
.map(b => Buffer.isBuffer(b) ? b.toString('hex') : b)
const inputScript = this.getInputScriptFromTransaction(claimTx)
return inputScript[2]
}
}
Expand Down
55 changes: 31 additions & 24 deletions packages/ethereum-swap-provider/lib/EthereumSwapProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ export default class EthereumSwapProvider extends Provider {

async verifyInitiateSwapTransaction (initiationTxHash, value, recipientAddress, refundAddress, secretHash, expiration) {
const initiationTransaction = await this.getMethod('getTransactionByHash')(initiationTxHash)
if (!initiationTransaction) return false

const initiationTransactionReceipt = await this.getMethod('getTransactionReceipt')(initiationTxHash)
const transactionMatchesSwapParams = this.doesTransactionMatchSwapParams(
initiationTransaction,
Expand All @@ -112,7 +114,7 @@ export default class EthereumSwapProvider extends Provider {
expiration
)

return transactionMatchesSwapParams && initiationTransactionReceipt.status === '1'
return transactionMatchesSwapParams && initiationTransactionReceipt && initiationTransactionReceipt.status === '1'
}

async findSwapTransaction (value, recipientAddress, refundAddress, secretHash, expiration, startBlock, predicate) {
Expand Down Expand Up @@ -172,22 +174,24 @@ export default class EthereumSwapProvider extends Provider {
const initiationTransaction = await this.getMethod('getTransactionReceipt')(initiationTxHash)
const block = await this.getMethod('getBlockByNumber')(blockNumber, true)

if (block && initiationTransaction) {
const transaction = block.transactions.find(
transaction => transaction.to === initiationTransaction.contractAddress
)
if (initiationTransaction) {
if (block) {
const transaction = block.transactions.find(
transaction => transaction.to === initiationTransaction.contractAddress
)

if (transaction) {
const transactionReceipt = await this.getMethod('getTransactionReceipt')(transaction.hash)
if (transactionReceipt.status === '1' && transaction.input !== '') claimSwapTransaction = transaction
}
if (transaction) {
const transactionReceipt = await this.getMethod('getTransactionReceipt')(transaction.hash)
if (transactionReceipt.status === '1' && transaction.input !== '') claimSwapTransaction = transaction
}

blockNumber++
} else {
arrivedAtTip = true
blockNumber++
} else {
arrivedAtTip = true
}
}

if (arrivedAtTip) { await sleep(5000) }
if (arrivedAtTip || !initiationTransaction) { await sleep(5000) }
}
claimSwapTransaction.secret = await this.getSwapSecret(claimSwapTransaction.hash)

Expand All @@ -201,25 +205,28 @@ export default class EthereumSwapProvider extends Provider {

async findRefundSwapTransaction (initiationTxHash, recipientAddress, refundAddress, secretHash, expiration, startBlock) {
let blockNumber = startBlock || await this.getMethod('getBlockHeight')()
const initiationTransaction = await this.getMethod('getTransactionReceipt')(initiationTxHash)
let refundSwapTransaction = false
let arrivedAtTip = false

while (!refundSwapTransaction) {
const initiationTransaction = await this.getMethod('getTransactionReceipt')(initiationTxHash)
const block = await this.getMethod('getBlockByNumber')(blockNumber, true)
if (block) {
refundSwapTransaction = block.transactions.find(transaction =>
transaction.to === initiationTransaction.contractAddress &&
transaction.input === '' &&
block.timestamp >= expiration
)

blockNumber++
} else {
arrivedAtTip = true
if (initiationTransaction) {
if (block) {
refundSwapTransaction = block.transactions.find(transaction =>
transaction.to === initiationTransaction.contractAddress &&
transaction.input === '' &&
block.timestamp >= expiration
)

blockNumber++
} else {
arrivedAtTip = true
}
}

if (arrivedAtTip) { await sleep(5000) }
if (arrivedAtTip || !initiationTransaction) { await sleep(5000) }
}
return refundSwapTransaction
}
Expand Down

0 comments on commit cb0adba

Please sign in to comment.