-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add batch functionality to core (#206)
Add batch dlc funding txs util functions to core including: - CoinSelect dualFundingCoinSelect - Builder buildCustomStrategyOrderOffer with multi contract support - CsoInfo getCsoInfoFromOffer decode bug fix (increment to V1 CsoInfo) Add tests for changes
- Loading branch information
1 parent
9ac2278
commit bb6b4ab
Showing
14 changed files
with
1,485 additions
and
183 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,4 +9,3 @@ test: | |
|
||
lint: | ||
yarn lint | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,9 @@ | |
"publish:all": "lerna publish from-package", | ||
"prepublishOnly": "npm run build" | ||
}, | ||
"pre-commit": [ "lint" ], | ||
"pre-commit": [ | ||
"lint" | ||
], | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
|
@@ -27,6 +29,7 @@ | |
"author": "Atomic Finance <[email protected]>", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@babel/runtime": "^7.24.0", | ||
"@istanbuljs/nyc-config-typescript": "^1.0.1", | ||
"@types/bn.js": "^4.11.6", | ||
"@types/chai": "^4.2.11", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
import { Value } from '@node-dlc/bitcoin'; | ||
import { expect } from 'chai'; | ||
|
||
import { dualFees, dualFundingCoinSelect, UTXO } from '../../lib'; | ||
|
||
const getUtxos = (totalCollateral: bigint, numUtxos = 1) => { | ||
const utxos: UTXO[] = []; | ||
|
||
for (let i = 0; i < numUtxos; i++) { | ||
utxos.push({ | ||
address: 'bcrt1qjzut0906d9sk4hml4k6sz6cssljktf4c7yl80f', | ||
txid: 'c7bf12ac16aba1cf6c7769117294853453f7da3006363dfe4e8979847e32f7e1', | ||
value: Math.ceil(Number(totalCollateral) / numUtxos), | ||
vout: Math.floor(Math.random() * 11), // random integer between 0 and 10 | ||
}); | ||
} | ||
|
||
return utxos; | ||
}; | ||
|
||
describe('CoinSelect', () => { | ||
describe('dualFundingCoinSelect', () => { | ||
it('should select coins correctly for 5 UTXOs and feeRate 450', () => { | ||
const feeRate = BigInt(450); | ||
const numUtxos = 5; | ||
const totalCollateral = Value.fromBitcoin(0.01); | ||
const offerCollateral = Value.fromBitcoin(0.0075); | ||
|
||
const utxos = getUtxos(totalCollateral.sats, numUtxos); | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
utxos, | ||
[offerCollateral.sats], | ||
feeRate, | ||
); | ||
|
||
expect(fee).to.equal(BigInt(217350)); | ||
expect(inputs.length).to.equal(5); | ||
}); | ||
|
||
it('should fail to select coins if fee is greater than sum of utxos', () => { | ||
const feeRate = BigInt(450); | ||
const numUtxos = 5; | ||
const totalCollateral = Value.fromBitcoin(0.01); | ||
const offerCollateral = Value.fromBitcoin(0.096); | ||
|
||
const utxos = getUtxos(totalCollateral.sats, numUtxos); | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
utxos, | ||
[offerCollateral.sats], | ||
feeRate, | ||
); | ||
|
||
expect(fee).to.equal(BigInt(94950)); | ||
expect(inputs.length).to.equal(0); | ||
}); | ||
|
||
it('should fail to select coins if detrimental input', () => { | ||
const feeRate = BigInt(450); | ||
const numUtxos = 1; | ||
const totalCollateral = Value.fromSats(30000); | ||
const offerCollateral = Value.fromSats(20000); | ||
|
||
const utxos = getUtxos(totalCollateral.sats, numUtxos); | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
utxos, | ||
[offerCollateral.sats], | ||
feeRate, | ||
); | ||
|
||
expect(fee).to.equal(BigInt(94950)); | ||
expect(inputs.length).to.equal(0); | ||
}); | ||
|
||
it('should prioritize utxo selection', () => { | ||
const feeRate = BigInt(450); | ||
const numUtxos = 5; | ||
const totalCollateral = Value.fromBitcoin(0.01); | ||
const offerCollateral = Value.fromBitcoin(0.0075); | ||
|
||
const utxos = getUtxos(totalCollateral.sats, numUtxos); | ||
|
||
utxos.push({ | ||
address: 'bcrt1qjzut0906d9sk4hml4k6sz6cssljktf4c7yl80f', | ||
txid: | ||
'c7bf12ac16aba1cf6c7769117294853453f7da3006363dfe4e8979847e32f7e1', | ||
value: 10000, | ||
vout: Math.floor(Math.random() * 11), // random integer between 0 and 10 | ||
}); | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
utxos, | ||
[offerCollateral.sats], | ||
feeRate, | ||
); | ||
|
||
expect(fee).to.equal(BigInt(217350)); | ||
expect(inputs.length).to.equal(5); | ||
}); | ||
}); | ||
|
||
describe('Additional CoinSelect Tests', () => { | ||
const feeRate = BigInt(450); | ||
const totalCollateral = Value.fromBitcoin(0.01); | ||
const offerCollateral = Value.fromBitcoin(0.0075); | ||
|
||
it('should fail to select coins when all UTXOs are detrimental due to high fee rate', () => { | ||
const highFeeRate = BigInt(10000); // An exaggerated fee rate to make the point | ||
const utxos = getUtxos(totalCollateral.sats, 5); | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
utxos, | ||
[offerCollateral.sats], | ||
highFeeRate, | ||
); | ||
|
||
expect(inputs.length).to.equal(0); | ||
expect(fee).to.equal(BigInt(2110000)); | ||
}); | ||
|
||
it('should select all UTXOs when they are just enough to cover collateral and fees', () => { | ||
const utxos = getUtxos(totalCollateral.sats, 5); | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
utxos, | ||
[offerCollateral.sats], | ||
feeRate, | ||
); | ||
|
||
expect(inputs.length).to.equal(5); | ||
expect(fee).to.equal(BigInt(217350)); | ||
}); | ||
|
||
it('should select UTXOs optimally from a mixed set', () => { | ||
const mixedUtxos = [ | ||
...getUtxos(Value.fromBitcoin(0.005).sats, 2), // smaller UTXOs | ||
...getUtxos(Value.fromBitcoin(0.02).sats, 3), // larger UTXOs | ||
]; | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
mixedUtxos, | ||
[offerCollateral.sats], | ||
feeRate, | ||
); | ||
|
||
// Expecting it to select fewer, larger UTXOs over many small ones | ||
expect(inputs.length).to.be.lessThan(5); | ||
expect(fee).to.equal(BigInt(125550)); | ||
}); | ||
|
||
it('should handle an empty array of UTXOs correctly', () => { | ||
const { fee, inputs } = dualFundingCoinSelect( | ||
[], | ||
[offerCollateral.sats], | ||
feeRate, | ||
); | ||
|
||
expect(inputs.length).to.equal(0); | ||
expect(fee).to.equal(dualFees(feeRate, 1, 1)); // The fee for an attempt with no inputs | ||
}); | ||
|
||
it('should select fewer UTXOs with a very low fee rate', () => { | ||
const lowFeeRate = BigInt(1); // An extremely low fee rate | ||
const utxos = getUtxos(totalCollateral.sats, 10); // More UTXOs than needed | ||
|
||
const { fee, inputs } = dualFundingCoinSelect( | ||
utxos, | ||
[offerCollateral.sats], | ||
lowFeeRate, | ||
); | ||
|
||
// Expecting it to select fewer UTXOs due to the low cost of adding an input | ||
expect(inputs.length).to.be.lessThan(10); | ||
expect(fee).to.equal(BigInt(687)); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.