PHP WebShell
Текущая директория: /opt/BitGoJS/modules/unspents/test/signedTx
Просмотр файла: txCombinations.ts
import should from 'should';
import { Dimensions } from '../../src';
import {
constructPsbt,
getInputDimensionsForUnspentType,
getOutputDimensionsForUnspentType,
TestUnspentType,
UnspentTypeP2shP2pk,
UnspentTypePubKeyHash,
UnspentTypeScript2of3,
} from '../testutils';
import { runCombinations, TxCombo } from './txGen';
import * as utxolib from '@bitgo/utxo-lib';
export type InputScriptType = utxolib.bitgo.outputScripts.ScriptType | 'taprootKeyPathSpend';
const keys = [1, 2, 3].map((v) =>
utxolib.bip32.fromSeed(Buffer.alloc(16, `test/2/${v}`), utxolib.networks.bitcoin)
) as utxolib.BIP32Interface[];
const rootWalletKeys = new utxolib.bitgo.RootWalletKeys([keys[0], keys[1], keys[2]]);
const testDimensionsFromTx = (txCombo: any) => {
const { inputTypes, outputTypes, expectedDims } = txCombo;
describe(`Combination inputs=${inputTypes}; outputs=${outputTypes}`, function () {
const nInputs = inputTypes.length;
const outputDims = Dimensions.sum(...outputTypes.map(getOutputDimensionsForUnspentType));
it(`calculates dimensions from unsigned transaction`, function () {
const unsignedTx = txCombo.getUnsignedTx();
// does not work for unsigned transactions
should.throws(() => Dimensions.fromTransaction(unsignedTx));
// unless explicitly allowed
Dimensions.fromTransaction(unsignedTx, { assumeUnsigned: Dimensions.ASSUME_P2SH }).should.eql(
Dimensions.sum({ nP2shInputs: nInputs }, outputDims)
);
Dimensions.fromTransaction(unsignedTx, { assumeUnsigned: Dimensions.ASSUME_P2SH_P2WSH }).should.eql(
Dimensions.sum({ nP2shP2wshInputs: nInputs }, outputDims)
);
Dimensions.fromTransaction(unsignedTx, { assumeUnsigned: Dimensions.ASSUME_P2WSH }).should.eql(
Dimensions.sum({ nP2wshInputs: nInputs }, outputDims)
);
});
it(`calculates dimensions for signed transaction`, function () {
const dimensions = Dimensions.fromTransaction(txCombo.getSignedTx());
dimensions.should.eql(expectedDims);
});
it(`calculates dimensions for signed input of transaction`, function () {
const signedTx = txCombo.getSignedTx();
// test Dimensions.fromInput()
inputTypes.forEach((input: any, i: number) =>
Dimensions.fromInput(signedTx.ins[i]).should.eql(Dimensions.sum(getInputDimensionsForUnspentType(input)))
);
});
});
};
const testDimensionsFromPsbt = (
keys: utxolib.bitgo.RootWalletKeys,
inputTypes: InputScriptType[],
outputTypes: TestUnspentType[],
expectedDims: Dimensions
) => {
describe(`Psbt Combination inputs=${inputTypes}; outputs=${outputTypes}`, function () {
(['unsigned', 'halfsigned', 'fullysigned'] as const).forEach((s) => {
it(`calculates dimensions from ${s} psbt`, function () {
const dimensions = Dimensions.fromPsbt(constructPsbt(keys, inputTypes, outputTypes, s));
dimensions.should.eql(expectedDims);
});
});
it(`calculates dimensions for signed input of psbt`, function () {
const signedPsbt = constructPsbt(keys, inputTypes, outputTypes, 'fullysigned');
inputTypes.forEach((input: any, i: number) =>
Dimensions.fromPsbtInput(signedPsbt.data.inputs[i]).should.eql(
Dimensions.sum(getInputDimensionsForUnspentType(input))
)
);
});
});
};
describe(`Dimensions for transaction combinations`, function () {
// p2trMusig2 is supported only with PSBT
const scriptTypes = utxolib.bitgo.outputScripts.scriptTypes2Of3.filter((t) => t !== 'p2trMusig2');
const params = {
inputTypes: [...scriptTypes, UnspentTypeP2shP2pk] as InputScriptType[],
maxNInputs: 2,
outputTypes: [...scriptTypes, ...Object.keys(UnspentTypePubKeyHash)] as TestUnspentType[],
maxNOutputs: 2,
};
runCombinations(params, (inputTypeCombo: InputScriptType[], outputTypeCombo: TestUnspentType[]) => {
const expectedInputDims = Dimensions.sum(...inputTypeCombo.map(getInputDimensionsForUnspentType));
const expectedOutputDims = Dimensions.sum(...outputTypeCombo.map(getOutputDimensionsForUnspentType));
testDimensionsFromTx(
new TxCombo(keys, inputTypeCombo, outputTypeCombo, expectedInputDims.plus(expectedOutputDims))
);
// Doubling the inputs should yield twice the input dims
testDimensionsFromTx(
new TxCombo(
keys,
[...inputTypeCombo, ...inputTypeCombo],
outputTypeCombo,
expectedInputDims.plus(expectedInputDims).plus(expectedOutputDims)
)
);
// Same for outputs
testDimensionsFromTx(
new TxCombo(
keys,
inputTypeCombo,
[...outputTypeCombo, ...outputTypeCombo],
expectedInputDims.plus(expectedOutputDims).plus(expectedOutputDims)
)
);
});
});
describe(`Dimensions for PSBT combinations`, function () {
const params = {
inputTypes: [
...utxolib.bitgo.outputScripts.scriptTypes2Of3,
utxolib.bitgo.outputScripts.scriptTypeP2shP2pk,
'taprootKeyPathSpend',
] as InputScriptType[],
maxNInputs: 1,
outputTypes: [...Object.keys(UnspentTypeScript2of3), ...Object.keys(UnspentTypePubKeyHash)],
maxNOutputs: 1,
};
it(`does not work for unknown psbt input`, function () {
const psbt = utxolib.bitgo.createPsbtForNetwork({ network: utxolib.networks.bitcoin });
psbt.addInput({ hash: Buffer.alloc(32), index: 0 });
should.throws(() => Dimensions.fromPsbt(psbt));
});
runCombinations(params, (inputTypeCombo: InputScriptType[], outputTypeCombo: TestUnspentType[]) => {
const expectedInputDims = Dimensions.sum(...inputTypeCombo.map(getInputDimensionsForUnspentType));
const expectedOutputDims = Dimensions.sum(...outputTypeCombo.map(getOutputDimensionsForUnspentType));
testDimensionsFromPsbt(rootWalletKeys, inputTypeCombo, outputTypeCombo, expectedInputDims.plus(expectedOutputDims));
// Doubling the inputs should yield twice the input dims
testDimensionsFromPsbt(
rootWalletKeys,
[...inputTypeCombo, ...inputTypeCombo],
outputTypeCombo,
expectedInputDims.plus(expectedInputDims).plus(expectedOutputDims)
);
// Same for outputs
testDimensionsFromPsbt(
rootWalletKeys,
inputTypeCombo,
[...outputTypeCombo, ...outputTypeCombo],
expectedInputDims.plus(expectedOutputDims).plus(expectedOutputDims)
);
});
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!