T3225
This diff updates getInputUtxos to take in additional params for custom output count and OP_RETURN bytecount. This is to prepare this library for subsequent SLP supporting diffs.
Differential D14417
[ecash-coinselect] Update getInputUtxos to support custom outputs and OP_RETURN bytecounts emack on Aug 26 2023, 01:08. Authored by Tags None Subscribers None
Details
T3225 This diff updates getInputUtxos to take in additional params for custom output count and OP_RETURN bytecount. This is to prepare this library for subsequent SLP supporting diffs. npm test
Diff Detail
Event Timeline
Comment Actions
Comment Actions @TODO: need to add ChronikMock in a separate diff in order to mock the chronik.script().utxos() api call within getInputUtxos(). Comment Actions Build Bitcoin ABC Diffs / Diff Testing (ecash-coinselect) failed.
Tail of the build log: Run `npm audit` for details. > ecash-coinselect@1.0.2 test > mocha --reporter mocha-junit-reporter --reporter-options mochaFile=test_results/ecash-coinselect-junit.xml --reporter-options testsuitesTitle=Ecash Coinselect Unit Tests --reporter-options rootSuiteTitle=Ecash Coinselect Error: Cannot find module 'ecashaddrjs' Require stack: - /work/modules/ecash-coinselect/src/utxo.js - /work/modules/ecash-coinselect/test/utxo.test.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1028:15) at Function.Module._load (node:internal/modules/cjs/loader:873:27) at Module.require (node:internal/modules/cjs/loader:1100:19) at require (node:internal/modules/cjs/helpers:119:18) at Object.<anonymous> (/work/modules/ecash-coinselect/src/utxo.js:5:133) at Module._compile (node:internal/modules/cjs/loader:1198:14) at Module.replacementCompile (/usr/lib/node_modules/nyc/node_modules/append-transform/index.js:60:13) at Module._extensions..js (node:internal/modules/cjs/loader:1252:10) at Object.<anonymous> (/usr/lib/node_modules/nyc/node_modules/append-transform/index.js:64:4) at Module.load (node:internal/modules/cjs/loader:1076:32) at Function.Module._load (node:internal/modules/cjs/loader:911:12) at Module.require (node:internal/modules/cjs/loader:1100:19) at require (node:internal/modules/cjs/helpers:119:18) at Object.<anonymous> (/work/modules/ecash-coinselect/test/utxo.test.js:11:5) at Module._compile (node:internal/modules/cjs/loader:1198:14) at Module.replacementCompile (/usr/lib/node_modules/nyc/node_modules/append-transform/index.js:60:13) at Module._extensions..js (node:internal/modules/cjs/loader:1252:10) at Object.<anonymous> (/usr/lib/node_modules/nyc/node_modules/append-transform/index.js:64:4) at Module.load (node:internal/modules/cjs/loader:1076:32) at Function.Module._load (node:internal/modules/cjs/loader:911:12) at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29) at ModuleJob.run (node:internal/modules/esm/module_job:193:25) at async Promise.all (index 0) at async ESMLoader.import (node:internal/modules/esm/loader:530:24) at async importModuleDynamicallyWrapper (node:internal/vm/module:438:15) at async formattedImport (/work/modules/ecash-coinselect/node_modules/mocha/lib/nodejs/esm-utils.js:9:14) at async Object.exports.requireOrImport (/work/modules/ecash-coinselect/node_modules/mocha/lib/nodejs/esm-utils.js:42:28) at async Object.exports.loadFilesAsync (/work/modules/ecash-coinselect/node_modules/mocha/lib/nodejs/esm-utils.js:100:20) at async singleRun (/work/modules/ecash-coinselect/node_modules/mocha/lib/cli/run-helpers.js:125:3) at async Object.exports.handler (/work/modules/ecash-coinselect/node_modules/mocha/lib/cli/run.js:370:5) ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 1.47 | 0 | 0 | 1.51 | utxo.js | 1.47 | 0 | 0 | 1.51 | 6-326 ----------|---------|----------|---------|---------|------------------- ##teamcity[blockOpened name='Code Coverage Summary'] ##teamcity[buildStatisticValue key='CodeCoverageAbsBCovered' value='1'] ##teamcity[buildStatisticValue key='CodeCoverageAbsBTotal' value='68'] ##teamcity[buildStatisticValue key='CodeCoverageAbsRCovered' value='0'] ##teamcity[buildStatisticValue key='CodeCoverageAbsRTotal' value='22'] ##teamcity[buildStatisticValue key='CodeCoverageAbsMCovered' value='0'] ##teamcity[buildStatisticValue key='CodeCoverageAbsMTotal' value='5'] ##teamcity[buildStatisticValue key='CodeCoverageAbsLCovered' value='1'] ##teamcity[buildStatisticValue key='CodeCoverageAbsLTotal' value='66'] ##teamcity[blockClosed name='Code Coverage Summary'] mv: cannot stat 'test_results/ecash-coinselect-junit.xml': No such file or directory Build ecash-coinselect failed with exit code 1 Comment Actions Rebased to D14423 and used the mock chronik from there to add new unit tests which mock the script().utxos() API calls from within getInputUtxos. Comment Actions This API doesn't work, on one hand you have the output count and on the other hand you expect the output to be a certain kind + have some op_return bytes.
Comment Actions Responding to feedback
No, the op_return outputs don't form part of the output count on the basis that op_return output is designated as unspendable.
The initial use case for this diff is a standard SLP tx, which only has one op_return output (index 0) along with p2pkh outputs as dust.
Comment Actions I think you're confused here. The output count is the actual txout vector of the transaction. It doesn't matter whether this is spendable or not, an op_return is unspendable but it's still an output of the transaction, and it adds 1 to the length of the txout vector. Having the output count be an inout parameter, and even worse with a default value (an out parameter with a default value makes absolutely zero sense) is also very convoluted. Like if I say I want 2 outputs, you can generate a single one because there is no change ? Is that the expected behavior ? Why should the callsite have to deal with a change output when the library is the one selecting the coins ? You should really think the API first before you start coding this. And not only the single use case of your example, but what a random eCash dev is expecting from a library called ecash-coinselect. Comment Actions
Point taken re: the outputCount. I had a look around, most notably the coinselect API consists of taking in:
So reviewing the current ecash-coinselect API:
i.e. function getP2pkhInputUtxos( chronikP2pkhUtxos, sendAmountInSats, tokenAction, opReturnByteCount = 0, ) ... return collectXecUtxos( chronikUtxos, sendAmountInSats, tokenAction, opReturnByteCount, ); Is this approach feasible? Comment Actions The token action seems like not what you want, at least not from the beginning. You can look at https://jlopp.github.io/bitcoin-transaction-size-calculator/ for inspiration. This can be extended with op_return outputs as needed. You should do it incrementally:
Now it's trivial to wrap up this selection function to make it easier to deal with the most common usages. |