Skip to content
This repository has been archived by the owner on Apr 15, 2021. It is now read-only.

Multi Sig Transactions #109

Merged
merged 24 commits into from Aug 24, 2020
Merged

Multi Sig Transactions #109

merged 24 commits into from Aug 24, 2020

Conversation

reedrosenbluth
Copy link
Contributor

@reedrosenbluth reedrosenbluth commented Aug 5, 2020

Description

This PR adds support for building Multi-Sig transactions.

Issue: #8

TODO

Type of Change

  • New feature
  • Bug fix
  • API reference/documentation update
  • Other

Does this introduce a breaking change?

List the APIs or describe the functionality that this PR breaks.
Workarounds for or expected timeline for deprecation

Are documentation updates required?

Testing information

Provide context on how tests should be performed.

  1. Is testing required for this change?
  2. If it’s a bug fix, list steps to reproduce the bug
  3. Briefly mention affected code paths
  4. List other affected projects if possible
  5. Things to watch out for when testing

Checklist

  • Code is commented where needed
  • Unit test coverage for new or modified code paths
  • npm run test passes
  • Changelog is updated
  • Tag 1 of @yknl, @zone117x, @reedrosenbluth for review

@project-bot project-bot bot added this to New issues in Splat Team Aug 5, 2020
@agraebe agraebe moved this from New issues to In progress in Splat Team Aug 10, 2020
@codecov
Copy link

codecov bot commented Aug 11, 2020

Codecov Report

Merging #109 into master will increase coverage by 1.15%.
The diff coverage is 86.44%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #109      +/-   ##
==========================================
+ Coverage   82.76%   83.91%   +1.15%     
==========================================
  Files          28       27       -1     
  Lines        2031     2052      +21     
  Branches      438      416      -22     
==========================================
+ Hits         1681     1722      +41     
+ Misses        346      326      -20     
  Partials        4        4              
Impacted Files Coverage Δ
src/types.ts 81.66% <60.00%> (-1.52%) ⬇️
src/builders.ts 75.26% <67.74%> (-1.98%) ⬇️
src/signer.ts 74.57% <73.33%> (+1.36%) ⬆️
src/transaction.ts 79.43% <90.00%> (+1.34%) ⬆️
src/authorization.ts 86.11% <91.27%> (+8.28%) ⬆️
src/utils.ts 97.46% <94.44%> (+17.70%) ⬆️
src/constants.ts 100.00% <100.00%> (ø)
src/keys.ts 90.42% <100.00%> (-0.11%) ⬇️
src/index.ts

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 29f23dc...ff911cf. Read the comment docs.

@reedrosenbluth reedrosenbluth marked this pull request as ready for review August 11, 2020 19:19
@agraebe agraebe linked an issue Aug 11, 2020 that may be closed by this pull request
@agraebe agraebe removed this from In progress in Splat Team Aug 11, 2020
@reedrosenbluth reedrosenbluth changed the title Multi Sig Multi Sig Transactions Aug 12, 2020

// Internally, the Stacks blockchain encodes address the same as Bitcoin
// multi-sig address (p2sh)
export const hashP2SH = (numSigs: number, pubKeys: Buffer[]): string => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No bitcoinjs-lib dependency? 💯

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work getting this to work without bitcoinjs-lib 👍

test('Single sig wpkh spending condition compressed', () => {
const addressHashMode = AddressHashMode.SerializeP2WPKH;
const nonce = new BigNum(345);
test('Multi sig spending condition uncompressed', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was the original test Single sig wpkh spending condition compressed intentionally removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was. It turns out that WPKH wasn't implemented yet. I'm not actually sure why that test was passing originally, but after my refactor it began to fail (with the expected Unimplemented Error) so I removed it

];

const spendingConditionBytes = Buffer.from(spendingConditionBytesHex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any test vectors copied from the rust codebase to ensure consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The multi-sig test in transaction-tests.js is mostly copied from the rust codebase, but I'm planning on adding some more test vectors. Will try and add some to this PR tomorrow

@zone117x
Copy link
Contributor

Love how clean this PR is. Code looks good. Before I approve I'd like to use this functionality in something (probably with a sidecar tx debug endpoint) for a good end-to-end test.

Copy link
Collaborator

@yknl yknl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good! Would love to see a builder function or a series of functions that help make the signing process easier.

src/builders.ts Outdated Show resolved Hide resolved
@@ -1,3 +1,5 @@
import * as _ from 'lodash';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this doesn't include the entire lodash bundle?

src/builders.ts Outdated
let spendingCondition = null;

if ('publicKey' in options) {
// multi-sig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would not be multi-sig case, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, this is a typo!

@agraebe agraebe linked an issue Aug 18, 2020 that may be closed by this pull request
@yknl
Copy link
Collaborator

yknl commented Aug 19, 2020

This looks good to merge 👍

@zone117x
Copy link
Contributor

zone117x commented Aug 19, 2020

There's a regression with sponsored transaction signing/serialization. Here's some data I collected to help debug.

A contract-call transaction's serialized payload:

// from this branch (this is an invalid tx):
80800000000500164247d6f2b425ac5771423ae6c80c754f7172b0000000000000000100000000000030390000d357ba68874c8d2b67c497c14af2e95f726b9e21f83f624acccfca20d2f15dbf4bf81da24564a550f4e96eef6922723a8d390943996aa300eecc2123b2df9eae0031ef5ee9a226a792b93f2bfbfbc54f523eba781800000000000000000000000000000118000111ed033667fd0ad5d4136455b5d0300d16c8daf496f1ecd09697db8e62164c7247537db17e1b7aa636cd8957d4c504a01d3e63a2b7eb89ff5f7b546351e8687e030100000000021a164247d6f2b425ac5771423ae6c80c754f7172b01468656c6c6f2d776f726c642d636f6e7472616374096765742d76616c7565000000010200000000

// from master branch (this is a valid tx):
80800000000500164247d6f2b425ac5771423ae6c80c754f7172b0000000000000000100000000000030390000d357ba68874c8d2b67c497c14af2e95f726b9e21f83f624acccfca20d2f15dbf4bf81da24564a550f4e96eef6922723a8d390943996aa300eecc2123b2df9eae0031ef5ee9a226a792b93f2bfbfbc54f523eba7818000000000000000000000000000001180000a24c32196623aa72f1d53324ffbf7d203ae8b148697aaef49ff8f809cdcab5e375bb9b84d3d1a0e60073458d9a8999c5b5941c0b248a0aa66b05fcbcc6d5657f030100000000021a164247d6f2b425ac5771423ae6c80c754f7172b01468656c6c6f2d776f726c642d636f6e7472616374096765742d76616c7565000000010200000000

Also, here's the error returned by the core-node when submitting the invalid transaction:

Error: Response 400: Bad Request fetching http://127.0.0.1:20443/v2/transactions:
{
  "error": "transaction rejected",
  "reason": "SignatureValidation",
  "reason_data": {
    "message": "Signer hash does not equal hash of public key(s): 9773d279b98a0e1388875729207fe7602cda7af5 != 31ef5ee9a226a792b93f2bfbfbc54f523eba7818"
  },
  "txid": "4a407703abe75fb5d1ad489875296d9eff52ad64bbf780b44d08d412ccb5faf9"
}

@zone117x
Copy link
Contributor

Draft PR in sidecar for supporting multisig transactions, currently helpful as an integration test with core-node hirosystems/stacks-blockchain-api#193

Core-node is rejecting multisig transactions with same error as the sponsored txs:

{
  "error": "transaction rejected",
  "reason": "SignatureValidation",
  "reason_data": {
    "message": "Signer hash does not equal hash of public key(s): fbcc4c8a97d1fe9d96cdf06c98ce05eccbc9ff35 != 55c50b056f6f2c500b4432b9e89828b3c8d607cf"
  },
  "txid": "54878b0cd7511af52d0ea901aa21c1f9f87c3ef254cb08bea8a82d1bb5aa4904"
}

@zone117x
Copy link
Contributor

zone117x commented Aug 21, 2020

Update: the latest commit fixes multisig transactions -- they are processed by the core-node as expected.

However, the sponsored transaction regression still exists.

@reedrosenbluth
Copy link
Contributor Author

Update: the latest commit fixes multisig transactions -- they are processed by the core-node as expected.

However, the sponsored transaction regression still exists.

I'm able to generate and submit a sponsored transaction with out any issues (on my local mocknet). @zone117x Can you sure some more detail about the transaction that isn't working for you?

Copy link
Contributor

@zone117x zone117x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sponsored tx regression has been fixed.

Additionally, sponsored + multisig transactions also work 👍

SHIP IT

@reedrosenbluth reedrosenbluth merged commit f41adb1 into master Aug 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for unsigned transactions Add multi-sig transaction generation
5 participants