Skip to content

Commit

Permalink
fix: update test and fix oversign check
Browse files Browse the repository at this point in the history
  • Loading branch information
reedrosenbluth committed Sep 2, 2021
1 parent 6ad03fd commit a26898e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
13 changes: 8 additions & 5 deletions packages/transactions/src/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { StacksTransaction } from './transaction';

import { StacksPrivateKey, StacksPublicKey } from './keys';
import { isSingleSig, nextVerification, SpendingConditionOpts } from './authorization';
import { cloneDeep, txidFromData } from './utils';
import { cloneDeep } from './utils';
import { AuthType, PubKeyEncoding, StacksMessageType } from './constants';
import { SigningError } from './errors';

Expand All @@ -24,8 +24,11 @@ export class TransactionSigner {
// auth fields and reconstruct sigHash
let spendingCondition = transaction.auth.spendingCondition;
if (spendingCondition && !isSingleSig(spendingCondition)) {

if (spendingCondition.fields.length >= spendingCondition.signaturesRequired) {
if (
spendingCondition.fields.filter(
field => field.contents.type === StacksMessageType.MessageSignature
).length >= spendingCondition.signaturesRequired
) {
throw new Error('SpendingCondition has more signatures than are expected');
}

Expand All @@ -42,11 +45,11 @@ export class TransactionSigner {
spendingCondition!.fee,
spendingCondition!.nonce,
PubKeyEncoding.Compressed, // always compressed for multisig
signature,
signature
);
this.sigHash = nextVerify.nextSigHash;
}
});
});
}
}

Expand Down
48 changes: 45 additions & 3 deletions packages/transactions/tests/builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { BufferReader } from '../src/bufferReader';

import { createAssetInfo } from '../src/types';

import { SingleSigSpendingCondition } from '../src/authorization';
import { createTransactionAuthField, MultiSigSpendingCondition, nextSignature, SingleSigSpendingCondition } from '../src/authorization';

import {
DEFAULT_CORE_NODE_API_URL,
Expand All @@ -41,14 +41,15 @@ import {
AuthType,
AddressHashMode,
AnchorMode,
PubKeyEncoding,
} from '../src/constants';

import { StacksTestnet, StacksMainnet } from '@stacks/network';

import { bufferCV, standardPrincipalCV, bufferCVFromString, serializeCV } from '../src/clarity';

import { ClarityAbi } from '../src/contract-abi';
import { createStacksPrivateKey, pubKeyfromPrivKey, publicKeyToString } from '../src/keys';
import { createStacksPrivateKey, isCompressed, pubKeyfromPrivKey, publicKeyToString } from '../src/keys';
import { TransactionSigner } from '../src/signer';
import fetchMock from 'jest-fetch-mock';

Expand Down Expand Up @@ -321,8 +322,23 @@ test('Make Multi-Sig STX token transfer with two transaction signers', async ()
const deserializedPayload = deserializedTx.payload as TokenTransferPayload;
expect(deserializedPayload.amount.toString()).toBe(amount.toString());


// obtain first auth field and sign once
const signer = new TransactionSigner(deserializedTx);
// sign once

const sig1 = nextSignature(
signer.sigHash,
authType,
deserializedTx.auth.spendingCondition!.fee,
deserializedTx.auth.spendingCondition!.nonce,
privKeys[0]
).nextSig;

const compressed1 = privKeys[0].data.toString('hex').endsWith('01');
const field1 = createTransactionAuthField(
compressed1 ? PubKeyEncoding.Compressed : PubKeyEncoding.Uncompressed,
sig1
)
signer.signOrigin(privKeys[0]);

// serialize
Expand All @@ -334,9 +350,35 @@ test('Make Multi-Sig STX token transfer with two transaction signers', async ()

// finish signing with new TransactionSigner
const signer2 = new TransactionSigner(partiallySigned);

const sig2 = nextSignature(
signer2.sigHash,
authType,
deserializedTx.auth.spendingCondition!.fee,
deserializedTx.auth.spendingCondition!.nonce,
privKeys[1]
).nextSig;

const compressed2 = privKeys[1].data.toString('hex').endsWith('01');
const field2 = createTransactionAuthField(
compressed2 ? PubKeyEncoding.Compressed : PubKeyEncoding.Uncompressed,
sig2
)

const compressedPub = isCompressed(pubKeys[2]);
const field3 = createTransactionAuthField(
compressedPub ? PubKeyEncoding.Compressed : PubKeyEncoding.Uncompressed,
pubKeys[2]
)

signer2.signOrigin(privKeys[1]);
signer2.appendOrigin(pubKeys[2]);

const spendingCondition = partiallySigned.auth.spendingCondition as MultiSigSpendingCondition;
expect(spendingCondition.fields[0]).toEqual(field1);
expect(spendingCondition.fields[1]).toEqual(field2);
expect(spendingCondition.fields[2]).toEqual(field3);

const serializedSignedTx = partiallySigned.serialize();

const signedTx =
Expand Down

0 comments on commit a26898e

Please sign in to comment.