From 68d13d75f19ccfeeaced5df2bac71880fe6011c1 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Sat, 22 Jul 2017 21:07:17 +0300 Subject: [PATCH] Modify jmclient tests for new protocol updates Add segwit tests in main test dir --- conftest.py | 2 +- jmclient/jmclient/wallet.py | 4 + jmclient/test/commontest.py | 8 +- jmclient/test/taker_test_data.py | 54 ++-- jmclient/test/test_client_protocol.py | 12 +- jmclient/test/test_configure.py | 18 +- jmclient/test/test_support.py | 6 +- jmclient/test/test_taker.py | 27 +- jmclient/test/test_tx_creation.py | 6 +- jmclient/test/test_wallets.py | 78 ++--- test/commontest.py | 5 +- test/test_segwit.py | 400 ++++++++++++++++++++++++++ test/tx_segwit_valid.json | 98 +++++++ 13 files changed, 613 insertions(+), 105 deletions(-) create mode 100644 test/test_segwit.py create mode 100644 test/tx_segwit_valid.json diff --git a/conftest.py b/conftest.py index 0162367..00d3262 100644 --- a/conftest.py +++ b/conftest.py @@ -89,7 +89,7 @@ def setup(request): #start up regtest blockchain btc_proc = subprocess.call([bitcoin_path + "bitcoind", "-regtest", "-daemon", "-conf=" + bitcoin_conf]) - time.sleep(1) + time.sleep(3) #generate blocks; segwit activates around block 500-600 for i in range(2): local_command([bitcoin_path + "bitcoin-cli", "-regtest", diff --git a/jmclient/jmclient/wallet.py b/jmclient/jmclient/wallet.py index aeb01d3..b9c168a 100644 --- a/jmclient/jmclient/wallet.py +++ b/jmclient/jmclient/wallet.py @@ -189,6 +189,8 @@ class Wallet(AbstractWallet): """for base/legacy wallet type, this is a passthrough. for bip39 style wallets, this will convert from one to the other """ + if entropy is None: + return None #Feature for testnet testing: if we are using direct command line #brainwallets (as we do for regtest), strip the flag. if entropy.startswith("FAKESEED"): @@ -393,6 +395,8 @@ class Bip39Wallet(Wallet): https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki """ def entropy_to_seed(self, entropy): + if entropy is None: + return None if get_network() == "testnet": if entropy.startswith("FAKESEED"): return entropy[8:] diff --git a/jmclient/test/commontest.py b/jmclient/test/commontest.py index 1461293..fc5cac2 100644 --- a/jmclient/test/commontest.py +++ b/jmclient/test/commontest.py @@ -13,7 +13,7 @@ import platform from decimal import Decimal from jmclient import (jm_single, Wallet, get_log, estimate_tx_fee, - BlockchainInterface) + BlockchainInterface, get_p2sh_vbyte) from jmbase.support import chunks import jmbitcoin as btc @@ -40,7 +40,8 @@ class DummyBlockchainInterface(BlockchainInterface): unconfirmfun, confirmfun, notifyaddr, - timeoutfun=None): + timeoutfun=None, + vb=None): pass def pushtx(self, txhex): @@ -86,7 +87,8 @@ class DummyBlockchainInterface(BlockchainInterface): return results if txouts[0] in known_outs: return [{'value': 200000000, - 'address': btc.pubkey_to_address(known_outs[txouts[0]], magicbyte=0x6f), + 'address': btc.pubkey_to_p2sh_p2wpkh_address( + known_outs[txouts[0]], get_p2sh_vbyte()), 'confirms': 20}] for t in txouts: result_dict = {'value': 10000000000, diff --git a/jmclient/test/taker_test_data.py b/jmclient/test/taker_test_data.py index 0b3dc67..278d10d 100644 --- a/jmclient/test/taker_test_data.py +++ b/jmclient/test/taker_test_data.py @@ -1,39 +1,39 @@ #orderbook -t_orderbook = [{u'counterparty': u'J5FA1Gj7Ln4vSGne', u'ordertype': u'reloffer', u'oid': 0, +t_orderbook = [{u'counterparty': u'J6FA1Gj7Ln4vSGne', u'ordertype': u'swreloffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, - {u'counterparty': u'J5CFffuuewjG44UJ', u'ordertype': u'reloffer', u'oid': 0, + {u'counterparty': u'J6CFffuuewjG44UJ', u'ordertype': u'swreloffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, - {u'counterparty': u'J55z23xdjxJjC7er', u'ordertype': u'reloffer', u'oid': 0, + {u'counterparty': u'J65z23xdjxJjC7er', u'ordertype': u'swreloffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, - {u'counterparty': u'J54Ghp5PXCdY9H3t', u'ordertype': u'reloffer', u'oid': 0, + {u'counterparty': u'J64Ghp5PXCdY9H3t', u'ordertype': u'swreloffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, - {u'counterparty': u'J559UPUSLLjHJpaB', u'ordertype': u'reloffer', u'oid': 0, + {u'counterparty': u'J659UPUSLLjHJpaB', u'ordertype': u'swreloffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, - {u'counterparty': u'J5cBx1FwUVh9zzoO', u'ordertype': u'reloffer', u'oid': 0, + {u'counterparty': u'J6cBx1FwUVh9zzoO', u'ordertype': u'swreloffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}] t_dest_addr = "mvw1NazKDRbeNufFANqpYNAANafsMC2zVU" -t_chosen_orders = {u'J559UPUSLLjHJpaB': {u'cjfee': u'0.0002', - u'counterparty': u'J559UPUSLLjHJpaB', +t_chosen_orders = {u'J659UPUSLLjHJpaB': {u'cjfee': u'0.0002', + u'counterparty': u'J659UPUSLLjHJpaB', u'maxsize': 599972700, u'minsize': 7500000, u'oid': 0, - u'ordertype': u'reloffer', + u'ordertype': u'swreloffer', u'txfee': 1000}, - u'J55z23xdjxJjC7er': {u'cjfee': u'0.0002', - u'counterparty': u'J55z23xdjxJjC7er', + u'J65z23xdjxJjC7er': {u'cjfee': u'0.0002', + u'counterparty': u'J65z23xdjxJjC7er', u'maxsize': 599972700, u'minsize': 7500000, u'oid': 0, - u'ordertype': u'reloffer', + u'ordertype': u'swreloffer', u'txfee': 1000}, - u'J5CFffuuewjG44UJ': {u'cjfee': u'0.0002', - u'counterparty': u'J5CFffuuewjG44UJ', + u'J6CFffuuewjG44UJ': {u'cjfee': u'0.0002', + u'counterparty': u'J6CFffuuewjG44UJ', u'maxsize': 599972700, u'minsize': 7500000, u'oid': 0, - u'ordertype': u'reloffer', + u'ordertype': u'swreloffer', u'txfee': 1000}} """ @@ -66,21 +66,21 @@ t_generated_podle = {'P': '025a2e04dc6bd5f58fe4eb13045b27f0dd17c39524264639f4860 'used': 'False', 'utxo': u'0780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1'} -t_maker_response = {"J559UPUSLLjHJpaB": +t_maker_response = {"J659UPUSLLjHJpaB": [["03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6:1"], "03a2d1cbe977b1feaf8d0d5cc28c686859563d1520b28018be0c2661cf1ebe4857", "mrKTGvFfYUEqk52qPKUroumZJcpjHLQ6pn", "mxPnzFkCQpPzVQdajNLoT4us5pTPsQZZZp", "MEQCIBeGrtxxVrj5tSUX6vEetmzE8nRBG/guSXq3SrqypIt5AiAnIZzDUXu8DtODgF2p1Bo27L8VcG1GJSfatZbS23YZQQ==", "5bcc7ae1a3530e454812668620aced47d774bf06a1f5870d531422a1a958b629"], - "J55z23xdjxJjC7er": + "J65z23xdjxJjC7er": [["498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3:0"], "02b4b749d54e96b04066b0803e372a43d6ffa16e75a001ae0ed4b235674ab286be", "mhatyHdna3Qt5FtnfwWaMVV1dohCaDYF3T", "mjJoVN2HCUGVDvNebiFnHdB3zF56bxQm5z", "MEQCIBlMF7DRbhr14e74He9m+UYjR5y8jjvP7TvUh8valebmAiBoIGjl436fsYim9pKSTbCKiBmT82hQ98LvIOGSLprk0A==", "8204d1cba30d4cdabab16a5e8d10d17464e24c78a6f887ae2d920b223c030d28"], - "J5CFffuuewjG44UJ": + "J6CFffuuewjG44UJ": [["3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c:1"], "023bcbafb4f68455e0d1d117c178b0e82a84e66414f0987453d78da034b299c3a9", "mpAEocXy8ckcJBo3fhQg9Mv1kfEzAuUivX", @@ -90,11 +90,11 @@ t_maker_response = {"J559UPUSLLjHJpaB": """ 2016-12-01 15:27:39,914 [MainThread ] [DEBUG] rpc: gettxout [u'03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6', 1, False] -2016-12-01 15:27:39,915 [MainThread ] [DEBUG] fee breakdown for J559UPUSLLjHJpaB totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 +2016-12-01 15:27:39,915 [MainThread ] [DEBUG] fee breakdown for J659UPUSLLjHJpaB totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 2016-12-01 15:27:39,915 [MainThread ] [DEBUG] rpc: gettxout [u'498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] -2016-12-01 15:27:39,915 [MainThread ] [DEBUG] fee breakdown for J55z23xdjxJjC7er totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 +2016-12-01 15:27:39,915 [MainThread ] [DEBUG] fee breakdown for J65z23xdjxJjC7er totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 2016-12-01 15:27:39,916 [MainThread ] [DEBUG] rpc: gettxout [u'3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c', 1, False] -2016-12-01 15:27:39,916 [MainThread ] [DEBUG] fee breakdown for J5CFffuuewjG44UJ totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 +2016-12-01 15:27:39,916 [MainThread ] [DEBUG] fee breakdown for J6CFffuuewjG44UJ totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 2016-12-01 15:27:39,916 [MainThread ] [DEBUG] INFO:Got all parts, enough to build a tx 2016-12-01 15:27:39,917 [MainThread ] [DEBUG] Estimated transaction size: 870 2016-12-01 15:27:39,917 [MainThread ] [DEBUG] rpc: estimatefee [3] @@ -140,9 +140,9 @@ t_obtained_tx = {'ins': [{'outpoint': {'hash': '03243f4a659e278a1333f8308f6aaf32 #signatures from makers """ -nick=J5CFffuuewjG44UJ message=!sig xH9IAMo2fvG+g+DAbLNOPsGsJCDm6r+ZY5QM7p+SRsixbqSwXcBQAn7Mnw1rS+uGlrJkM8ossX5VHKjdKDhTXQVLawR7XgiVFFFiO+/FjdFhqVuS4Q/NgOlb7nCBe/UaBebd9NpuURG+8u/V+46jtqKRtVsSO1+QZQBt2nSpYCqxWIjxMowRxS4O/zlrOVbyjv/AjchOajufKJwckkrkJDyQDYlUdW+eqs43tf0XsJ9k4NHRVVHAQQ== 036558f550b1d398d2325d892e50ef25b0f663ae13f70d0b304a15f07030061ace MEUCIQCE9MgU+HfcHkKE8zNzNeCEdDBJuQatA6C2sTJ9mVKK7wIgX4w9r0tz4s9qeuW0UjNliDatJ4X7pS3/atADSqPat0U= -nick=J559UPUSLLjHJpaB message=!sig geHTf1n88eKeUnVOj7bIrJF1KFCN03IQhZD0cR17Q7jPSn2DZrrvMaRNkjZRyF+zGnWFwd69kwLRU0ftCaMf/3lw+05UovVCREiyXWUtPJa7XAY2NW4iMmTnGTp8f9RLgDcDhiZayKXTpzBDC9r6WAt6wiD0lej5uw7dmluKSUyfXW8sOYPmLm4iJAPcbGeJiQfiR9zBeX8w+6Kz4bkaiue41SzQP/h9avPV2XIX4kVQQ3jLfQyHww== 038f90ab260df440cef82a981146b509eb9df019884e145158230e8babc17d7be4 MEQCIEo5Pau9zqW2lw+B2AYTYuTO5TDbBkgsOk0bqT+SQctKAiBO1nbsmYTy7E0Qd7jAxko1Gq6Yk0Q6DerByuEuk5IBSQ== -nick=J55z23xdjxJjC7er message=!sig A5CWvqmYCOiZBEEi9iHVpQL0oO9B7VIIzuU9QhkzXOw+iD916C9b+Yk3eTxrtf+qaLARQ7eui6zdPNek95EdmqCEqM/myeeuBVSy9KrcB9xU0sdnuCu4+g13jVe9Pkvd1iizZ8GCNP7SejEzeltNr0a1lR+M0kKtj4XI+nDTxhisSzL8PDXsqoOMcrDjegna3TZsJeKviu8r/1T/zWwTQtRCXqruLnflqXNLtZoyFmoaO1GurgkNHA== 029a8beadec242f04f2295787ac0175b960e2d68d115ec65c4310de7ce3fa2cec0 MEQCIHpTxVkwtvm7agbp47Z5V0We8jxXkfZDUFsW2tZwTZdHAiA9JnYvo74hF3RihzHw2l+ufTOmC/3ddBpxkB9+AdZvzA== +nick=J6CFffuuewjG44UJ message=!sig xH9IAMo2fvG+g+DAbLNOPsGsJCDm6r+ZY5QM7p+SRsixbqSwXcBQAn7Mnw1rS+uGlrJkM8ossX5VHKjdKDhTXQVLawR7XgiVFFFiO+/FjdFhqVuS4Q/NgOlb7nCBe/UaBebd9NpuURG+8u/V+46jtqKRtVsSO1+QZQBt2nSpYCqxWIjxMowRxS4O/zlrOVbyjv/AjchOajufKJwckkrkJDyQDYlUdW+eqs43tf0XsJ9k4NHRVVHAQQ== 036558f550b1d398d2325d892e50ef25b0f663ae13f70d0b304a15f07030061ace MEUCIQCE9MgU+HfcHkKE8zNzNeCEdDBJuQatA6C2sTJ9mVKK7wIgX4w9r0tz4s9qeuW0UjNliDatJ4X7pS3/atADSqPat0U= +nick=J659UPUSLLjHJpaB message=!sig geHTf1n88eKeUnVOj7bIrJF1KFCN03IQhZD0cR17Q7jPSn2DZrrvMaRNkjZRyF+zGnWFwd69kwLRU0ftCaMf/3lw+05UovVCREiyXWUtPJa7XAY2NW4iMmTnGTp8f9RLgDcDhiZayKXTpzBDC9r6WAt6wiD0lej5uw7dmluKSUyfXW8sOYPmLm4iJAPcbGeJiQfiR9zBeX8w+6Kz4bkaiue41SzQP/h9avPV2XIX4kVQQ3jLfQyHww== 038f90ab260df440cef82a981146b509eb9df019884e145158230e8babc17d7be4 MEQCIEo5Pau9zqW2lw+B2AYTYuTO5TDbBkgsOk0bqT+SQctKAiBO1nbsmYTy7E0Qd7jAxko1Gq6Yk0Q6DerByuEuk5IBSQ== +nick=J65z23xdjxJjC7er message=!sig A5CWvqmYCOiZBEEi9iHVpQL0oO9B7VIIzuU9QhkzXOw+iD916C9b+Yk3eTxrtf+qaLARQ7eui6zdPNek95EdmqCEqM/myeeuBVSy9KrcB9xU0sdnuCu4+g13jVe9Pkvd1iizZ8GCNP7SejEzeltNr0a1lR+M0kKtj4XI+nDTxhisSzL8PDXsqoOMcrDjegna3TZsJeKviu8r/1T/zWwTQtRCXqruLnflqXNLtZoyFmoaO1GurgkNHA== 029a8beadec242f04f2295787ac0175b960e2d68d115ec65c4310de7ce3fa2cec0 MEQCIHpTxVkwtvm7agbp47Z5V0We8jxXkfZDUFsW2tZwTZdHAiA9JnYvo74hF3RihzHw2l+ufTOmC/3ddBpxkB9+AdZvzA== """ """ @@ -151,14 +151,14 @@ nick=J55z23xdjxJjC7er message=!sig A5CWvqmYCOiZBEEi9iHVpQL0oO9B7VIIzuU9QhkzXOw+i 2016-12-01 15:27:39,968 [MainThread ] [DEBUG] rpc: gettxout ['3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c', 1, False] 2016-12-01 15:27:39,969 [MainThread ] [DEBUG] rpc: gettxout ['498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] 2016-12-01 15:27:39,971 [MainThread ] [DEBUG] found good sig at index=1 -2016-12-01 15:27:39,971 [MainThread ] [DEBUG] nick = J5CFffuuewjG44UJ sent all sigs, removing from nonrespondant list +2016-12-01 15:27:39,971 [MainThread ] [DEBUG] nick = J6CFffuuewjG44UJ sent all sigs, removing from nonrespondant list 2016-12-01 15:27:39,971 [MainThread ] [DEBUG] rpc: gettxout ['03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6', 1, False] 2016-12-01 15:27:39,972 [MainThread ] [DEBUG] rpc: gettxout ['498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] 2016-12-01 15:27:39,973 [MainThread ] [DEBUG] found good sig at index=0 -2016-12-01 15:27:39,973 [MainThread ] [DEBUG] nick = J559UPUSLLjHJpaB sent all sigs, removing from nonrespondant list +2016-12-01 15:27:39,973 [MainThread ] [DEBUG] nick = J659UPUSLLjHJpaB sent all sigs, removing from nonrespondant list 2016-12-01 15:27:43,937 [MainThread ] [DEBUG] rpc: gettxout ['498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] 2016-12-01 15:27:43,938 [MainThread ] [DEBUG] found good sig at index=2 -2016-12-01 15:27:43,938 [MainThread ] [DEBUG] nick = J55z23xdjxJjC7er sent all sigs, removing from nonrespondant list +2016-12-01 15:27:43,938 [MainThread ] [DEBUG] nick = J65z23xdjxJjC7er sent all sigs, removing from nonrespondant list 2016-12-01 15:27:43,938 [MainThread ] [DEBUG] all makers have sent their signatures 2016-12-01 15:27:43,938 [MainThread ] [DEBUG] INFO:Transaction is valid, signing.. 2016-12-01 15:27:43,943 [MainThread ] [DEBUG] diff --git a/jmclient/test/test_client_protocol.py b/jmclient/test/test_client_protocol.py index de5ab24..cbbfb27 100644 --- a/jmclient/test/test_client_protocol.py +++ b/jmclient/test/test_client_protocol.py @@ -4,7 +4,7 @@ from __future__ import absolute_import import pytest from jmclient import (get_schedule, load_program_config, start_reactor, - Taker, get_log, JMTakerClientProtocolFactory, jm_single) + Taker, get_log, JMClientProtocolFactory, jm_single) from jmclient.client_protocol import JMProtocolError, JMTakerClientProtocol import os from twisted.python.log import startLogging, err @@ -129,8 +129,8 @@ class JMTestServerProtocol(JMBaseProtocol): return {'accepted': True} @JMSetup.responder - def on_JM_SETUP(self, role, n_counterparties): - show_receipt("JMSETUP", role,n_counterparties) + def on_JM_SETUP(self, role, initdata): + show_receipt("JMSETUP", role, initdata) d = self.callRemote(JMSetupDone) self.defaultCallbacks(d) return {'accepted': True} @@ -204,9 +204,9 @@ class JMTestServerProtocol(JMBaseProtocol): class JMTestServerProtocolFactory(protocol.ServerFactory): protocol = JMTestServerProtocol -class DummyClientProtocolFactory(JMTakerClientProtocolFactory): +class DummyClientProtocolFactory(JMClientProtocolFactory): def buildProtocol(self, addr): - return JMTakerClientProtocol(self, self.taker, nick_priv="aa"*32) + return JMTakerClientProtocol(self, self.client, nick_priv="aa"*32) class TrialTestJMClientProto(unittest.TestCase): @@ -228,7 +228,7 @@ class TrialTestJMClientProto(unittest.TestCase): takers[i].set_fail_utxos(p[1]) takers[i].testflag = True if i != 0: - clientfactories.append(JMTakerClientProtocolFactory(takers[i])) + clientfactories.append(JMClientProtocolFactory(takers[i])) clientconn = reactor.connectTCP("localhost", 27184, clientfactories[i]) self.addCleanup(clientconn.disconnect) else: diff --git a/jmclient/test/test_configure.py b/jmclient/test/test_configure.py index 549867f..b94d1ba 100644 --- a/jmclient/test/test_configure.py +++ b/jmclient/test/test_configure.py @@ -4,8 +4,7 @@ from __future__ import absolute_import import pytest from jmclient import (load_program_config, jm_single, get_irc_mchannels, - BTC_P2PK_VBYTE, BTC_P2SH_VBYTE, check_utxo_blacklist, - validate_address) + BTC_P2PK_VBYTE, BTC_P2SH_VBYTE, validate_address) from jmclient.configure import (get_config_irc_channel, get_p2sh_vbyte, get_p2pk_vbyte, get_blockchain_interface_instance) import jmbitcoin as bitcoin @@ -46,21 +45,6 @@ def test_net_byte(): assert get_p2pk_vbyte() == 0x6f assert get_p2sh_vbyte() == 196 -def test_check_blacklist(): - load_program_config() - jm_single().nickname = "fortestnick" - fn = "blacklist" + "_" + jm_single().nickname - if os.path.exists(fn): - os.remove(fn) - assert check_utxo_blacklist("aa"*32, False) - with open(fn, "wb") as f: - f.write("aa"*32 + "\n") - assert not check_utxo_blacklist("aa"*32, False) - assert check_utxo_blacklist("bb"*32, False) - assert check_utxo_blacklist("bb"*32, True) - assert not check_utxo_blacklist("bb"*32, False) - assert not check_utxo_blacklist("bb"*32, True) - def test_blockchain_sources(): load_program_config() for src in ["blockr", "electrum", "dummy", "bc.i"]: diff --git a/jmclient/test/test_support.py b/jmclient/test/test_support.py index a82ecf1..bf81bfc 100644 --- a/jmclient/test/test_support.py +++ b/jmclient/test/test_support.py @@ -54,8 +54,8 @@ def test_random_funcs(): assert e_info.match("Need: 5 probabilities.") def test_calc_cjfee(): - assert calc_cj_fee("absoffer", 3000, 200000000) == 3000 - assert calc_cj_fee("reloffer", "0.01", 100000000) == 1000000 + assert calc_cj_fee("swabsoffer", 3000, 200000000) == 3000 + assert calc_cj_fee("swreloffer", "0.01", 100000000) == 1000000 with pytest.raises(RuntimeError) as e_info: calc_cj_fee("dummyoffer", 2, 3) @@ -101,7 +101,7 @@ def test_choose_orders(): #(b) add an unrecognized ordertype #(c) put an order with wrong minsize orderbook.append({u'counterparty': u'fake', - u'ordertype': u'absoffer', u'oid': 0, + u'ordertype': u'swabsoffer', u'oid': 0, u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': 9000}) result, cjamount, total_fee = choose_sweep_orders(orderbook, 50000000, diff --git a/jmclient/test/test_taker.py b/jmclient/test/test_taker.py index 4e286cf..f0d0d2a 100644 --- a/jmclient/test/test_taker.py +++ b/jmclient/test/test_taker.py @@ -10,7 +10,8 @@ import pytest import json from base64 import b64encode from jmclient import (load_program_config, jm_single, set_commitment_file, - get_commitment_file, AbstractWallet, Taker) + get_commitment_file, AbstractWallet, Taker, + get_p2sh_vbyte) from taker_test_data import (t_utxos_by_mixdepth, t_selected_utxos, t_orderbook, t_maker_response, t_chosen_orders, t_dummy_ext) @@ -38,6 +39,22 @@ class DummyWallet(AbstractWallet): print("Pretending to sign on addresses: " + str(addrs)) return tx + def sign(self, tx, i, priv, amount): + """Sign a transaction; the amount field + triggers the segwit style signing. + """ + print("About to sign for this amount: " + str(amount)) + return tx + + def get_txtype(self): + """Return string defining wallet type + for purposes of transaction size estimates + """ + return 'p2sh-p2wpkh' + + def get_vbyte(self): + return get_p2sh_vbyte() + def get_key_from_addr(self, addr): """usable addresses: privkey all 1s, 2s, 3s, ... :""" privs = [x*32 + "\x01" for x in [chr(y) for y in range(1,6)]] @@ -199,7 +216,7 @@ def test_auth_pub_not_found(createcmtdata): ([(0, 5000000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw", 0)], False, True, 2, False, None, None), #test too much coins ([(0, 0, 5, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw", 0)], False, False, - 2, False, ["J559UPUSLLjHJpaB", "J55z23xdjxJjC7er", 0], None), #test inadequate for sweep + 2, False, ["J659UPUSLLjHJpaB", "J65z23xdjxJjC7er", 0], None), #test inadequate for sweep ]) def test_taker_init(createcmtdata, schedule, highfee, toomuchcoins, minmakers, notauthed, ignored, nocommit): @@ -242,7 +259,7 @@ def test_taker_init(createcmtdata, schedule, highfee, toomuchcoins, minmakers, maker_response = copy.deepcopy(t_maker_response) if notauthed: #Doctor one of the maker response data fields - maker_response["J559UPUSLLjHJpaB"][1] = "xx" #the auth pub + maker_response["J659UPUSLLjHJpaB"][1] = "xx" #the auth pub if schedule[0][1] == 199850000: #triggers negative change #makers offer 3000 txfee; we estimate ~ 147*10 + 2*34 + 10=1548 bytes @@ -310,7 +327,7 @@ def test_taker_init(createcmtdata, schedule, highfee, toomuchcoins, minmakers, with pytest.raises(NotImplementedError) as e_info: taker.prepare_my_bitcoin_data() with pytest.raises(NotImplementedError) as e_info: - taker.sign_tx("a", "b", "c") + taker.sign_tx("a", "b", "c", "d") with pytest.raises(NotImplementedError) as e_info: a = taker.coinjoin_address() taker.wallet.inject_addr_get_failure = True @@ -421,7 +438,7 @@ def test_on_sig(createcmtdata, dummyaddr, signmethod, schedule): ]) def test_auth_counterparty(schedule): taker = get_taker(schedule=schedule) - first_maker_response = t_maker_response["J559UPUSLLjHJpaB"] + first_maker_response = t_maker_response["J659UPUSLLjHJpaB"] utxo, auth_pub, cjaddr, changeaddr, sig, maker_pub = first_maker_response auth_pub_tweaked = auth_pub[:8] + auth_pub[6:8] + auth_pub[10:] sig_tweaked = sig[:8] + sig[6:8] + sig[10:] diff --git a/jmclient/test/test_tx_creation.py b/jmclient/test/test_tx_creation.py index f5ceb19..ecae414 100644 --- a/jmclient/test/test_tx_creation.py +++ b/jmclient/test/test_tx_creation.py @@ -77,9 +77,9 @@ def test_mktx(setup_tx_creation): tx = bitcoin.mktx(ins, outs) def test_bintxhash(setup_tx_creation): - tx = "abcd" + tx = "abcdef1234" x = bitcoin.bin_txhash(tx) - assert binascii.hexlify(x) == "943cbb9637d9b16b92529b182ed0257ec729afc897ac0522b2ed2a86f6809917" + assert binascii.hexlify(x) == "121480fc2cccd5103434a9c88b037e08ef6c4f9f95dfb85b56f7043a344613fe" def test_all_same_priv(setup_tx_creation): #recipient @@ -205,7 +205,7 @@ def test_spend_p2sh_utxos(setup_tx_creation): txid = make_sign_and_push(ins_full, wallet, amount, output_addr=msig_addr) assert txid #wait for mining - time.sleep(4) + time.sleep(1) #spend out; the input can be constructed from the txid of previous msig_in = txid + ":0" ins = [msig_in] diff --git a/jmclient/test/test_wallets.py b/jmclient/test/test_wallets.py index 459205a..b898e67 100644 --- a/jmclient/test/test_wallets.py +++ b/jmclient/test/test_wallets.py @@ -23,7 +23,7 @@ from jmclient import (load_program_config, jm_single, sync_wallet, AbstractWallet, get_p2pk_vbyte, get_log, Wallet, select, select_gradual, select_greedy, select_greediest, estimate_tx_fee, encryptData, get_network, WalletError, - BitcoinCoreWallet, BitcoinCoreInterface) + BitcoinCoreWallet, BitcoinCoreInterface, SegwitWallet) from jmbase.support import chunks from taker_test_data import t_obtained_tx, t_raw_signed_tx testdir = os.path.dirname(os.path.realpath(__file__)) @@ -49,6 +49,7 @@ def do_tx(wallet, amount): def test_query_utxo_set(setup_wallets): load_program_config() + jm_single().bc_interface.tick_forward_chain_interval = 1 wallet = create_wallet_for_sync("wallet4utxo.json", "4utxo", [2, 3, 0, 0, 0], ["wallet4utxo.json", "4utxo", [2, 3]]) @@ -105,20 +106,20 @@ def create_wallet_for_sync(wallet_file, password, wallet_structure, a): 'import-pwd'), #Uncomment all these for thorough tests. Passing currently. #Lots of used addresses - (7, 1, [51, 3, 4, 5, 6], 150000000, 'test_import_wallet.json', - 'import-pwd'), - (3, 1, [3, 1, 4, 5, 6], 50000000, 'test_import_wallet.json', - 'import-pwd'), + #(7, 1, [51, 3, 4, 5, 6], 150000000, 'test_import_wallet.json', + # 'import-pwd'), + #(3, 1, [3, 1, 4, 5, 6], 50000000, 'test_import_wallet.json', + # 'import-pwd'), #No spams/fakes - (2, 0, [5, 20, 1, 1, 1], 50000000, 'test_import_wallet.json', - 'import-pwd'), + #(2, 0, [5, 20, 1, 1, 1], 50000000, 'test_import_wallet.json', + # 'import-pwd'), #Lots of transactions and fakes - (25, 30, [30, 20, 1, 1, 1], 50000000, 'test_import_wallet.json', - 'import-pwd'), + #(25, 30, [30, 20, 1, 1, 1], 50000000, 'test_import_wallet.json', + # 'import-pwd'), ]) def test_wallet_sync_with_fast(setup_wallets, num_txs, fake_count, wallet_structure, amount, wallet_file, password): - + jm_single().bc_interface.tick_forward_chain_interval = 1 wallet = create_wallet_for_sync(wallet_file, password, wallet_structure, [num_txs, fake_count, wallet_structure, amount, wallet_file, password]) @@ -338,9 +339,9 @@ def create_default_testnet_wallet(): pathtowallet = os.path.join(walletdir, testwalletname) if os.path.exists(pathtowallet): os.remove(pathtowallet) - seed = "hello" + seed = "deadbeef" return (walletdir, pathtowallet, testwalletname, - Wallet(seed, + SegwitWallet(seed, None, 5, 6, @@ -350,8 +351,10 @@ def create_default_testnet_wallet(): @pytest.mark.parametrize( "includecache, wrongnet, storepwd, extendmd, pwdnumtries", [ - (False, False, False, False, 1000), (True, False, False, True, 1), - (False, True, False, False, 1), (False, False, True, False, 1) + (False, False, False, False, 100), + (True, False, False, True, 1), + (False, True, False, False, 1), + (False, False, True, False, 1) ]) def test_wallet_create(setup_wallets, includecache, wrongnet, storepwd, extendmd, pwdnumtries): @@ -359,15 +362,15 @@ def test_wallet_create(setup_wallets, includecache, wrongnet, storepwd, ) assert wallet.get_key( 4, 1, - 17) == "1289ca322f96673acef83f396a9735840e3ab69f0459cf9bfa8d9985a876534401" - assert wallet.get_addr(2, 0, 5) == "myWPu9QJWHGE79XAmuKkwKgNk8vsr5evpk" + 17) == "96095d7542e4e832c476b9df7e49ca9e5be61ad3bb8c8a3bdd8e141e2f4caf9101" + assert wallet.get_addr(2, 0, 5) == "2NBUxbEQrGPKrYCV6d4o7Y4AtJ34Uy6gZZg" jm_single().bc_interface.wallet_synced = True - assert wallet.get_new_addr(1, 0) == "mi88ZgDGPmarzcsU6S437h9CY9BLmgH5M6" - assert wallet.get_external_addr(3) == "mvChQuChnXVhqvH67wfMxrodPQ7xccdVJU" + assert wallet.get_new_addr(1, 0) == "2Mz817RE6zqywgkG2h9cATUoiXwnFSxufk2" + assert wallet.get_external_addr(3) == "2N3gn65WXEzbLnjk5FLDZPc1pL6ebvZAmoA" addr3internal = wallet.get_internal_addr(3) - assert addr3internal == "mv26o79Bauf2miJMoxoSu1vXmfXnk85YPQ" + assert addr3internal == "2N5NMTYogAyrGhDtWBnVQUp1kgwwFzcf7UM" assert wallet.get_key_from_addr( - addr3internal) == "2a283c9a2168a25509e2fb944939637228c50c8b4fecd9024650316c4584246501" + addr3internal) == "089a7173314d29f99e02a37e36da517ce41537a317c83284db1f33dda0af0cc201" dummyaddr = "mvw1NazKDRbeNufFANqpYNAANafsMC2zVU" assert not wallet.get_key_from_addr(dummyaddr) #Make a new Wallet(), and prepare a testnet wallet file for this wallet @@ -393,7 +396,7 @@ def test_wallet_create(setup_wallets, includecache, wrongnet, storepwd, f.write(walletfile) if wrongnet: with pytest.raises(ValueError) as e_info: - Wallet(testwalletname, + SegwitWallet(testwalletname, password, 5, 6, @@ -406,7 +409,7 @@ def test_wallet_create(setup_wallets, includecache, wrongnet, storepwd, with pytest.raises(WalletError) as e_info: wrongpwd = "".join([random.choice(ascii_letters) for _ in range(20) ]) - Wallet(testwalletname, + SegwitWallet(testwalletname, wrongpwd, 5, 6, @@ -414,19 +417,19 @@ def test_wallet_create(setup_wallets, includecache, wrongnet, storepwd, storepassword=storepwd) with pytest.raises(WalletError) as e_info: - Wallet(testwalletname, + SegwitWallet(testwalletname, None, 5, 6, extend_mixdepth=extendmd, storepassword=storepwd) - newwallet = Wallet(testwalletname, + newwallet = SegwitWallet(testwalletname, password, 5, 6, extend_mixdepth=extendmd, storepassword=storepwd) - assert newwallet.seed == seed + assert newwallet.seed == wallet.entropy_to_seed(seed) #now we have a functional wallet + file, update the cache; first try #with failed paths oldpath = newwallet.path @@ -500,26 +503,24 @@ def test_imported_privkey(setup_wallets): jm_single().bc_interface.sync_wallet(newwallet) load_program_config() - def test_add_remove_utxos(setup_wallets): #Make a fake wallet and inject and then remove fake utxos - walletdir, pathtowallet, testwalletname, wallet = create_default_testnet_wallet( - ) - assert wallet.get_addr(2, 0, 5) == "myWPu9QJWHGE79XAmuKkwKgNk8vsr5evpk" - wallet.addr_cache["myWPu9QJWHGE79XAmuKkwKgNk8vsr5evpk"] = (2, 0, 5) - #'76a914c55738deaa9861b6022e53a129968cbf354898b488ac' + walletdir, pathtowallet, testwalletname, wallet = create_default_testnet_wallet() + assert wallet.get_addr(2, 0, 5) == "2NBUxbEQrGPKrYCV6d4o7Y4AtJ34Uy6gZZg" + wallet.addr_cache["2NBUxbEQrGPKrYCV6d4o7Y4AtJ34Uy6gZZg"] = (2, 0, 5) + #'a914c80b3c03b96c0da5ef983942d9e541cb788aed8787' #these calls automatically update the addr_cache: - assert wallet.get_new_addr(1, 0) == "mi88ZgDGPmarzcsU6S437h9CY9BLmgH5M6" - #76a9141c9761f5fef73bef6aca378c930c59e7e795088488ac - assert wallet.get_external_addr(3) == "mvChQuChnXVhqvH67wfMxrodPQ7xccdVJU" - #76a914a115fa0394ce881437a96d443e236b39e07db1f988ac + assert wallet.get_new_addr(1, 0) == "2Mz817RE6zqywgkG2h9cATUoiXwnFSxufk2" + #a9144b6b3836a1708fd38d4728e41b86e69d5bb15d5187 + assert wallet.get_external_addr(3) == "2N3gn65WXEzbLnjk5FLDZPc1pL6ebvZAmoA" + #a914728673d95ceafa892ed82f9cc23c8bf1700b6c6187 #using the above pubkey scripts: faketxforwallet = {'outs': [ - {'script': '76a914c55738deaa9861b6022e53a129968cbf354898b488ac', + {'script': 'a914c80b3c03b96c0da5ef983942d9e541cb788aed8787', 'value': 110000000}, - {'script': '76a9141c9761f5fef73bef6aca378c930c59e7e795088488ac', + {'script': 'a9144b6b3836a1708fd38d4728e41b86e69d5bb15d5187', 'value': 89910900}, - {'script': '76a914a115fa0394ce881437a96d443e236b39e07db1f988ac', + {'script': 'a914728673d95ceafa892ed82f9cc23c8bf1700b6c6187', 'value': 90021000}, {'script': '76a9145ece2dac945c8ff5b2b6635360ca0478ade305d488ac', #not ours @@ -554,3 +555,4 @@ def test_add_remove_utxos(setup_wallets): @pytest.fixture(scope="module") def setup_wallets(): load_program_config() + jm_single().bc_interface.tick_forward_chain_interval = 2 diff --git a/test/commontest.py b/test/commontest.py index 8ff993f..3be1c40 100644 --- a/test/commontest.py +++ b/test/commontest.py @@ -62,7 +62,8 @@ def make_wallets(n, start_index=0, fixed_seeds=None, test_wallet=False, - passwords=None): + passwords=None, + walletclass=SegwitWallet): '''n: number of wallets to be created wallet_structure: array of n arrays , each subarray specifying the number of addresses to be populated with coins @@ -84,7 +85,7 @@ def make_wallets(n, if test_wallet: w = TestWallet(seeds[i], max_mix_depth=5, pwd=passwords[i]) else: - w = SegwitWallet(seeds[i], pwd=None, max_mix_depth=5) + w = walletclass(seeds[i], pwd=None, max_mix_depth=5) wallets[i + start_index] = {'seed': seeds[i], 'wallet': w} for j in range(5): diff --git a/test/test_segwit.py b/test/test_segwit.py new file mode 100644 index 0000000..c66df53 --- /dev/null +++ b/test/test_segwit.py @@ -0,0 +1,400 @@ +#! /usr/bin/env python +from __future__ import absolute_import +'''Test creation of segwit transactions.''' + +import sys +import os +import time +import binascii +import json +from commontest import make_wallets +from pprint import pformat +import jmbitcoin as btc +import pytest +from jmclient import (load_program_config, jm_single, get_p2pk_vbyte, + get_log, get_p2sh_vbyte, Wallet) +log = get_log() + + +def test_segwit_valid_txs(setup_segwit): + with open("test/tx_segwit_valid.json", "r") as f: + json_data = f.read() + valid_txs = json.loads(json_data) + for j in valid_txs: + if len(j) < 2: + continue + deserialized_tx = btc.deserialize(str(j[1])) + print pformat(deserialized_tx) + assert btc.serialize(deserialized_tx) == str(j[1]) + #TODO use bcinterface to decoderawtransaction + #and compare the json values + + +def get_utxo_from_txid(txid, addr): + """Given a txid and an address for one of the outputs, + return "txid:n" where n is the index of the output + """ + rawtx = jm_single().bc_interface.rpc("getrawtransaction", [txid, 1]) + ins = [] + for u in rawtx["vout"]: + if u["scriptPubKey"]["addresses"][0] == addr: + ins.append(txid + ":" + str(u["n"])) + assert len(ins) == 1 + return ins[0] + + +def make_sign_and_push(ins_sw, + wallet, + amount, + other_ins=None, + output_addr=None, + change_addr=None, + hashcode=btc.SIGHASH_ALL): + """A more complicated version of the function in test_tx_creation; + will merge to this one once finished. + ins_sw have this structure: + {"txid:n":(amount, priv, index), "txid2:n2":(amount2, priv2, index2), ..} + if other_ins is not None, it has the same format, + these inputs are assumed to be plain p2pkh. + All of these inputs in these two sets will be consumed. + They are ordered according to the "index" fields (to allow testing + of specific ordering) + It's assumed that they contain sufficient coins to satisy the + required output specified in "amount", plus some extra for fees and a + change output. + The output_addr and change_addr, if None, are taken from the wallet + and are ordinary p2pkh outputs. + All amounts are in satoshis and only converted to btc for grab_coins + """ + #total value of all inputs + print ins_sw + print other_ins + total = sum([x[0] for x in ins_sw.values()]) + total += sum([x[0] for x in other_ins.values()]) + #construct the other inputs + ins1 = other_ins + ins1.update(ins_sw) + ins1 = sorted(ins1.keys(), key=lambda k: ins1[k][2]) + #random output address and change addr + output_addr = wallet.get_new_addr(1, 1) if not output_addr else output_addr + change_addr = wallet.get_new_addr(1, 0) if not change_addr else change_addr + outs = [{'value': amount, + 'address': output_addr}, {'value': total - amount - 10000, + 'address': change_addr}] + tx = btc.mktx(ins1, outs) + de_tx = btc.deserialize(tx) + for index, ins in enumerate(de_tx['ins']): + utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index']) + temp_ins = ins_sw if utxo in ins_sw.keys() else other_ins + amt, priv, n = temp_ins[utxo] + temp_amt = amt if utxo in ins_sw.keys() else None + #for better test code coverage + print "signing tx index: " + str(index) + ", priv: " + priv + if index % 2: + priv = binascii.unhexlify(priv) + ms = "other" if not temp_amt else "amount: " + str(temp_amt) + print ms + tx = btc.sign(tx, index, priv, hashcode=hashcode, amount=temp_amt) + print pformat(btc.deserialize(tx)) + txid = jm_single().bc_interface.pushtx(tx) + time.sleep(3) + received = jm_single().bc_interface.get_received_by_addr( + [output_addr], None)['data'][0]['balance'] + #check coins were transferred as expected + assert received == amount + #pushtx returns False on any error + return txid + + +@pytest.mark.parametrize( + "wallet_structure, in_amt, amount, segwit_amt, segwit_ins, o_ins", [ + ([[1, 0, 0, 0, 0]], 1, 1000000, 1, [0, 1, 2], []), + ([[4, 0, 0, 0, 1]], 3, 100000000, 1, [0, 2], [1, 3]), + ([[4, 0, 0, 0, 1]], 3, 100000000, 1, [0, 5], [1, 2, 3, 4]), + ([[2, 0, 0, 0, 2]], 2, 200000007, 0.3, [0, 1, 4, 5], [2, 3, 6]), + ]) +def test_spend_p2sh_p2wpkh_multi(setup_segwit, wallet_structure, in_amt, amount, + segwit_amt, segwit_ins, o_ins): + """Creates a wallet from which non-segwit inputs/ + outputs can be created, constructs one or more + p2wpkh in p2sh spendable utxos (by paying into the + corresponding address) and tests spending them + in combination. + wallet_structure is in accordance with commontest.make_wallets, see docs there + in_amt is the amount to pay into each address into the wallet (non-segwit adds) + amount (in satoshis) is how much we will pay to the output address + segwit_amt in BTC is the amount we will fund each new segwit address with + segwit_ins is a list of input indices (where to place the funding segwit utxos) + other_ins is a list of input indices (where to place the funding non-sw utxos) + """ + wallet = make_wallets(1, wallet_structure, in_amt, walletclass=Wallet)[0]['wallet'] + jm_single().bc_interface.sync_wallet(wallet) + other_ins = {} + ctr = 0 + for k, v in wallet.unspent.iteritems(): + #only extract as many non-segwit utxos as we need; + #doesn't matter which they are + if ctr == len(o_ins): + break + other_ins[k] = (v["value"], wallet.get_key_from_addr(v["address"]), + o_ins[ctr]) + ctr += 1 + ins_sw = {} + for i in range(len(segwit_ins)): + #build segwit ins from "deterministic-random" keys; + #intended to be the same for each run with the same parameters + seed = json.dumps([i, wallet_structure, in_amt, amount, segwit_ins, + other_ins]) + priv = btc.sha256(seed) + "01" + pub = btc.privtopub(priv) + #magicbyte is testnet p2sh + addr1 = btc.pubkey_to_p2sh_p2wpkh_address(pub, magicbyte=196) + print "got address for p2shp2wpkh: " + addr1 + txid = jm_single().bc_interface.grab_coins(addr1, segwit_amt) + #TODO - int cast, fix? + ins_sw[get_utxo_from_txid(txid, addr1)] = (int(segwit_amt * 100000000), + priv, segwit_ins[i]) + #make_sign_and_push will sanity check the received amount is correct + txid = make_sign_and_push(ins_sw, wallet, amount, other_ins) + #will always be False if it didn't push. + assert txid + + +@pytest.fixture(scope="module") +def setup_segwit(): + load_program_config() + jm_single().bc_interface.tick_forward_chain_interval = 1 + + +''' +Examples of valid segwit from the json with parsing + +["Valid P2WPKH (Private key of segwit tests is +L5AQtV2HDm4xGsseLokK2VAT2EtYKcTm3c7HwqnJBFt9LdaQULsM)"], + +[[["0000000000000000000000000000000000000000000000000000000000000100", +0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]], + +"01000000 +00 +01 +ins start +in num +01 +in txid +000100000000000000000000000000000000000000000000000000000000000000 +in txid out index +00000000 +sequence +ffffffff +num outs +01 +amount +e803000000000000 +script +1976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac +(number of witnesses = 1, implied by txin length) +witnesses : number 1 +item count for this witness +02 +signature length +48 +signature + hashcode 01 +3045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc4450220 +0a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed01 +pubkey length +21 +pubkey +03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 +locktime +00000000", "P2SH,WITNESS"], +''' +''' +P2WSH example +01000000 +00 +01 +01 +00010000000000000000000000000000000000000000000000000000000000000000 +000000 +ffffffff +01 +amount +e803000000000000 +length 25 +19 +OP_DUP OP_HASH160 +76a9 +hash length +14 +ripemd160(sha256(pubkey)) +4c9c3dfac4207d5d8cb89df5722cb3d712385e3f +OP_EQUALVERIFY OP_CHECKSIG +88ac +num items in witness 1 +02 +length of sig +48 +3045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb0220 +22dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01 +length of scriptSig +23 +length of pubkey +21 +pubkey +03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 +CHECKSIG +ac +locktime +00000000 + +" +Example with SIGHASH_SINGLE|SIGHASH_ANYONECANPAY +version +01000000 +marker +00 +flag +01 +num in +04 +in1 txid +0001000000000000000000000000000000000000000000000000000000000000 +in 1 index +0200000000 +in 1 sequence +ffffffff +0001000000000000000000000000000000000000000000000000000000000000 +0100000000 +ffffffff +0001000000000000000000000000000000000000000000000000000000000000 +0000000000 +ffffffff +0001000000000000000000000000000000000000000000000000000000000000 +0300000000 +ffffffff +num outs +05 +out 0 amount +540b000000000000 +length +01 +OP_TRUE - looks like anyonecanspend +51 +out 1 +amount +d007000000000000 +length +01 +OP_TRUE +51 +out 2 +amount +8403000000000000 +length +01 +OP_TRUE +51 +out 3 +amount +3c0f000000000000 +length +01 +OP_TRUE +51 +out 4 +amount +2c01000000000000 +length +01 +OP_TRUE +51 +witness starts here +first txin witness - none +00 +second witness item +num items in witness +02 +sig length +48 +signature +304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb869 +02206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e983 - SIGHASH_SINGLE|SIGHASH_ANYONECANPAY +length pubkey +21 +pubkey +03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 +locktime +000000000000 + + +"01000000 +00 +01 +01 +0001000000000000000000000000000000000000000000000000000000000000 +0000000000 +ffffffff +01 +e803000000000000 +19 +76a9 +14 +4c9c3dfac4207d5d8cb89df5722cb3d712385e3f +88 +ac +02 +48 +3045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb +022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01 +23 +21 +03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 +ac +00000000", "P2SH,WITNESS"], + + +["Valid P2SH(P2WPKH)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", +0, +**NOTE: this hash160 is of 00 14 ** - how P2SHP2WPKH works +"HASH160 0x14 0xfe9c7dacc9fcfbf7e3b7d5ad06aa2b28c5a7b7e3 EQUAL", 1000]], + +" +01000000 +00 +01 +01 +0001000000000000000000000000000000000000000000000000000000000000 +00000000 +length of scriptsig +17 +length of item +16 +witness versoin byte +00 +length of item +14 +hash160 - of PUBKEY +4c9c3dfac4207d5d8cb89df5722cb3d712385e3f +sequence +ffffffff +num outs +01 +amount +e803000000000000 +output +1976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac +witness for input 0 +num items +02 +48 +3045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc445 +02200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed01 +len pub +21 +pub +03596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71 +locktime +00000000", "P2SH,WITNESS"], +''' diff --git a/test/tx_segwit_valid.json b/test/tx_segwit_valid.json new file mode 100644 index 0000000..7fe0cdd --- /dev/null +++ b/test/tx_segwit_valid.json @@ -0,0 +1,98 @@ +[ +["Valid P2WPKH (Private key of segwit tests is L5AQtV2HDm4xGsseLokK2VAT2EtYKcTm3c7HwqnJBFt9LdaQULsM)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Valid P2WSH"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3db", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"], + +["Valid P2SH(P2WPKH)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xfe9c7dacc9fcfbf7e3b7d5ad06aa2b28c5a7b7e3 EQUAL", 1000]], +"01000000000101000100000000000000000000000000000000000000000000000000000000000000000000171600144c9c3dfac4207d5d8cb89df5722cb3d712385e3fffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000", "P2SH,WITNESS"], + +["Valid P2SH(P2WSH)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x2135ab4f0981830311e35600eebc7376dce3a914 EQUAL", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000023220020ff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff05540b0000000000000151d0070000000000000151840300000000000001513c0f00000000000001512c010000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71000000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210092f4777a0f17bf5aeb8ae768dec5f2c14feabf9d1fe2c89c78dfed0f13fdb86902206da90a86042e252bcd1e80a168c719e4a1ddcc3cebea24b9812c5453c79107e9832103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff0484030000000000000151d0070000000000000151540b0000000000000151c800000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash Single (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b000000000000015100024730440220699e6b0cfe015b64ca3283e6551440a34f901ba62dd4c72fe1cb815afb2e6761022021cc5e84db498b1479de14efda49093219441adc6c543e5534979605e273d80b032103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff04b60300000000000001519e070000000000000151860b00000000000001009600000000000000015100000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000248304502210091b32274295c2a3fa02f5bce92fb2789e3fc6ea947fbe1a76e52ea3f4ef2381a022079ad72aefa3837a2e0c033a8652a59731da05fa4a813f4fc48e87c075037256b822103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff04b60300000000000001519e070000000000000151860b0000000000000100960000000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash None (same signature, only sequences changed)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"01000000000103000100000000000000000000000000000000000000000000000000000000000000000000000200000000010000000000000000000000000000000000000000000000000000000000000100000000ffffffff000100000000000000000000000000000000000000000000000000000000000002000000000200000003e8030000000000000151d0070000000000000151b80b00000000000001510002473044022022fceb54f62f8feea77faac7083c3b56c4676a78f93745adc8a35800bc36adfa022026927df9abcf0a8777829bcfcce3ff0a385fa54c3f9df577405e3ef24ee56479022103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1100], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3100], +["0000000000000000000000000000000000000000000000000000000000000100", 3, "0x51", 4100]], +"0100000000010400010000000000000000000000000000000000000000000000000000000000000200000000ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000300000000ffffffff03e8030000000000000151d0070000000000000151b80b0000000000000151000002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with SigHash All|AnyoneCanPay (same signature as previous)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x00 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623eeef89e0ba1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Unknown witness program version with invalid signature"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x51", 1000], +["0000000000000000000000000000000000000000000000000000000000000100", 1, "0x51 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f", 2000], +["0000000000000000000000000000000000000000000000000000000000000100", 2, "0x51", 3000]], +"0100000000010300010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff00010000000000000000000000000000000000000000000000000000000000000200000000ffffffff03e8030000000000000151d0070000000000000151b80b00000000000001510002483045022100a3cec69b52cba2d2de623ffffffffff1606184ea55476c0f8189fda231bc9cbb022003181ad597f7c380a7d1c740286b1d022b8b04ded028b833282e055e03b8efef812103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "P2SH,WITNESS"], + +["Witness with a push of 520 bytes"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x00 0x20 0x33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349", 1000]], +"0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015102fd08020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002755100000000", "P2SH,WITNESS"], + +["Make diffs cleaner by leaving a comment here without comma at the end"] +]