Example #1
0
    def run_test(self):
        # Check regression: https://github.com/bitcoin/bitcoin/issues/6963#issuecomment-154548880
        x = self.nodes[0].validateaddress('3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
        assert (x['isvalid'] == False)
        x = self.nodes[0].validateaddress(
            convert_btc_address_to_mmchain(
                'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ'))
        assert (x['isvalid'] == True)

        # Checking mining to an address without a wallet
        try:
            self.nodes[0].generatetoaddress(
                1,
                convert_btc_address_to_mmchain(
                    'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ'))
        except JSONRPCException as e:
            assert ("Invalid address" not in e.error['message'])
            assert ("ProcessNewBlock, block not accepted"
                    not in e.error['message'])
            assert ("Couldn't create new block" not in e.error['message'])

        try:
            self.nodes[0].generatetoaddress(
                1, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
            raise AssertionError("Must not mine to invalid address!")
        except JSONRPCException as e:
            assert ("Invalid address" in e.error['message'])
Example #2
0
def create_witnessprogram(version, node, utxo, pubkey, encode_p2sh, amount):
    pkscript = witness_script(version, pubkey)
    if (encode_p2sh):
        p2sh_hash = bytes_to_hex_str(
            ripemd160(sha256(hex_str_to_bytes(pkscript))))
        pkscript = "a914" + p2sh_hash + "87"
    inputs = []
    outputs = {}
    inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]})
    DUMMY_P2SH = convert_btc_address_to_mmchain(
        "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2")  # P2SH of "OP_1 OP_DROP"
    outputs[DUMMY_P2SH] = amount
    tx_to_witness = node.createrawtransaction(inputs, outputs)
    tx_to_witness = tx_to_witness[0:110] + addlength(
        pkscript) + tx_to_witness[-8:]
    return tx_to_witness
Example #3
0
    def run_test(self):
        message = 'This is just a test message'

        # Test the signing with a privkey
        privKey = 'cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N'
        address = convert_btc_address_to_mmchain(
            'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB')
        signature = self.nodes[0].signmessagewithprivkey(privKey, message)

        # Verify the message
        assert (self.nodes[0].verifymessage(address, signature, message))

        # Test the signing with an address with wallet
        address = self.nodes[0].getnewaddress()
        signature = self.nodes[0].signmessage(address, message)

        # Verify the message
        assert (self.nodes[0].verifymessage(address, signature, message))
Example #4
0
    def successful_signing_test(self):
        """Creates and signs a valid raw transaction with one input.

        Expected results:

        1) The transaction has a complete set of signatures
        2) No script verification error occurred"""
        privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA']

        inputs = [
            # Valid pay-to-pubkey scripts
            {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
             'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
            {'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0,
             'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'},
        ]

        outputs = {convert_btc_address_to_mmchain('mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB'): 0.1}

        rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
        rawTxSigned = self.nodes[0].signrawtransaction(rawTx, inputs, privKeys)

        # 1) The transaction has a complete set of signatures
        assert 'complete' in rawTxSigned
        assert_equal(rawTxSigned['complete'], True)

        # 2) No script verification error occurred
        assert 'errors' not in rawTxSigned

        # Check that signrawtransaction doesn't blow up on garbage merge attempts
        dummyTxInconsistent = self.nodes[0].createrawtransaction([inputs[0]], outputs)
        rawTxUnsigned = self.nodes[0].signrawtransaction(rawTx + dummyTxInconsistent, inputs)

        assert 'complete' in rawTxUnsigned
        assert_equal(rawTxUnsigned['complete'], False)

        # Check that signrawtransaction properly merges unsigned and signed txn, even with garbage in the middle
        rawTxSigned2 = self.nodes[0].signrawtransaction(rawTxUnsigned["hex"] + dummyTxInconsistent + rawTxSigned["hex"], inputs)

        assert 'complete' in rawTxSigned2
        assert_equal(rawTxSigned2['complete'], True)

        assert 'errors' not in rawTxSigned2
Example #5
0
    def run_test(self):
        self.nodes[0].generate(161)  #block 161

        # We submit some non-segwit-signalling blocks to delay activation until the coinbases have matured
        for i in range(4 * 144 - 161):
            block = create_block(
                int(self.nodes[0].getbestblockhash(), 16),
                create_coinbase(self.nodes[0].getblockcount() + 1),
                int(time.time()) + 2 + i)
            block.nVersion = 4
            block.hashMerkleRoot = block.calc_merkle_root()
            block.rehash()
            block.solve()
            self.nodes[0].submitblock(bytes_to_hex_str(block.serialize()))
        self.nodes[0].generate(17)

        print(
            "Verify sigops are counted in GBT with pre-BIP141 rules before the fork"
        )
        txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
        tmpl = self.nodes[0].getblocktemplate({})
        assert (tmpl['sizelimit'] == 2000000)
        assert ('weightlimit' not in tmpl)
        assert (tmpl['sigoplimit'] == 20000)
        assert (tmpl['transactions'][0]['hash'] == txid)
        assert (tmpl['transactions'][0]['sigops'] == 2)
        tmpl = self.nodes[0].getblocktemplate({'rules': ['segwit']})
        assert (tmpl['sizelimit'] == 2000000)
        assert ('weightlimit' not in tmpl)
        assert (tmpl['sigoplimit'] == 20000)
        assert (tmpl['transactions'][0]['hash'] == txid)
        assert (tmpl['transactions'][0]['sigops'] == 2)
        self.nodes[0].generate(1)  #block 162

        balance_presetup = self.nodes[0].getbalance()
        self.pubkey = []
        p2sh_ids = [
        ]  # p2sh_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE embedded in p2sh
        wit_ids = [
        ]  # wit_ids[NODE][VER] is an array of txids that spend to a witness version VER pkscript to an address for NODE via bare witness
        for i in range(3):
            newaddress = self.nodes[i].getnewaddress()
            self.pubkey.append(
                self.nodes[i].validateaddress(newaddress)["pubkey"])
            multiaddress = self.nodes[i].addmultisigaddress(
                1, [self.pubkey[-1]])
            self.nodes[i].addwitnessaddress(newaddress)
            self.nodes[i].addwitnessaddress(multiaddress)
            p2sh_ids.append([])
            wit_ids.append([])
            for v in range(2):
                p2sh_ids[i].append([])
                wit_ids[i].append([])

        for i in range(5):
            for n in range(3):
                for v in range(2):
                    wit_ids[n][v].append(
                        send_to_witness(
                            v, self.nodes[0],
                            find_unspent(self.nodes[0], INITIAL_BLOCK_REWARD),
                            self.pubkey[n], False,
                            Decimal(str(INITIAL_BLOCK_REWARD - 0.001))))
                    p2sh_ids[n][v].append(
                        send_to_witness(
                            v, self.nodes[0],
                            find_unspent(self.nodes[0], INITIAL_BLOCK_REWARD),
                            self.pubkey[n], True,
                            Decimal(str(INITIAL_BLOCK_REWARD - 0.001))))

        self.nodes[0].generate(1)  #block 163
        sync_blocks(self.nodes)

        # Make sure all nodes recognize the transactions as theirs
        assert_equal(
            self.nodes[0].getbalance(),
            balance_presetup - 60 * int(INITIAL_BLOCK_REWARD) +
            20 * Decimal(str(INITIAL_BLOCK_REWARD - 0.001)) +
            int(INITIAL_BLOCK_REWARD))
        assert_equal(self.nodes[1].getbalance(),
                     20 * Decimal(str(INITIAL_BLOCK_REWARD - 0.001)))
        assert_equal(self.nodes[2].getbalance(),
                     20 * Decimal(str(INITIAL_BLOCK_REWARD - 0.001)))

        self.nodes[0].generate(260)  #block 423
        sync_blocks(self.nodes)

        print(
            "Verify default node can't accept any witness format txs before fork"
        )
        # unsigned, no scriptsig
        self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], False)
        self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], False)
        self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False)
        self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False)
        # unsigned with redeem script
        self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False,
                         addlength(witness_script(0, self.pubkey[0])))
        self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False,
                         addlength(witness_script(1, self.pubkey[0])))
        # signed
        self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True)
        self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], True)
        self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], True)
        self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], True)

        print("Verify witness txs are skipped for mining before the fork")
        self.skip_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][0],
                       True)  #block 424
        self.skip_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][0],
                       True)  #block 425
        self.skip_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][0],
                       True)  #block 426
        self.skip_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][0],
                       True)  #block 427

        # TODO: An old node would see these txs without witnesses and be able to mine them

        print(
            "Verify unsigned bare witness txs in versionbits-setting blocks are valid before the fork"
        )
        self.success_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][1],
                          False)  #block 428
        self.success_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][1],
                          False)  #block 429

        print(
            "Verify unsigned p2sh witness txs without a redeem script are invalid"
        )
        self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False)
        self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False)

        print(
            "Verify unsigned p2sh witness txs with a redeem script in versionbits-settings blocks are valid before the fork"
        )
        self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False,
                          addlength(witness_script(
                              0, self.pubkey[2])))  #block 430
        self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False,
                          addlength(witness_script(
                              1, self.pubkey[2])))  #block 431

        print(
            "Verify previous witness txs skipped for mining can now be mined")
        assert_equal(len(self.nodes[2].getrawmempool()), 4)
        block = self.nodes[2].generate(
            1)  #block 432 (first block with new rules; 432 = 144 * 3)
        sync_blocks(self.nodes)
        assert_equal(len(self.nodes[2].getrawmempool()), 0)
        segwit_tx_list = self.nodes[2].getblock(block[0])["tx"]
        assert_equal(len(segwit_tx_list), 5)

        print(
            "Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag"
        )
        assert (self.nodes[2].getblock(block[0], False) !=
                self.nodes[0].getblock(block[0], False))
        assert (self.nodes[1].getblock(block[0],
                                       False) == self.nodes[2].getblock(
                                           block[0], False))
        for i in range(len(segwit_tx_list)):
            tx = FromHex(
                CTransaction(),
                self.nodes[2].gettransaction(segwit_tx_list[i])["hex"])
            assert (self.nodes[2].getrawtransaction(segwit_tx_list[i]) !=
                    self.nodes[0].getrawtransaction(segwit_tx_list[i]))
            assert (self.nodes[1].getrawtransaction(
                segwit_tx_list[i],
                0) == self.nodes[2].getrawtransaction(segwit_tx_list[i]))
            assert (self.nodes[0].getrawtransaction(segwit_tx_list[i]) !=
                    self.nodes[2].gettransaction(segwit_tx_list[i])["hex"])
            assert (self.nodes[1].getrawtransaction(
                segwit_tx_list[i]) == self.nodes[2].gettransaction(
                    segwit_tx_list[i])["hex"])
            assert (self.nodes[0].getrawtransaction(
                segwit_tx_list[i]) == bytes_to_hex_str(
                    tx.serialize_without_witness()))

        print(
            "Verify witness txs without witness data are invalid after the fork"
        )
        self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False)
        self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][2], False)
        self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][2], False,
                       addlength(witness_script(0, self.pubkey[2])))
        self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][2], False,
                       addlength(witness_script(1, self.pubkey[2])))

        print("Verify default node can now use witness txs")
        self.success_mine(self.nodes[0], wit_ids[NODE_0][WIT_V0][0],
                          True)  #block 432
        self.success_mine(self.nodes[0], wit_ids[NODE_0][WIT_V1][0],
                          True)  #block 433
        self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0],
                          True)  #block 434
        self.success_mine(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0],
                          True)  #block 435

        print(
            "Verify sigops are counted in GBT with BIP141 rules after the fork"
        )
        txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
        tmpl = self.nodes[0].getblocktemplate({'rules': ['segwit']})
        assert (
            tmpl['sizelimit'] >= 3999577
        )  # actual maximum size is lower due to minimum mandatory non-witness data
        assert (tmpl['weightlimit'] == 8000000)
        assert (tmpl['sigoplimit'] == 80000)
        assert (tmpl['transactions'][0]['txid'] == txid)
        assert (tmpl['transactions'][0]['sigops'] == 8)

        print(
            "Verify non-segwit miners get a valid GBT response after the fork")
        send_to_witness(1, self.nodes[0],
                        find_unspent(self.nodes[0], int(INITIAL_BLOCK_REWARD)),
                        self.pubkey[0], False,
                        Decimal(str(INITIAL_BLOCK_REWARD - 0.002)))
        try:
            tmpl = self.nodes[0].getblocktemplate({})
            assert (len(tmpl['transactions']) == 1
                    )  # Doesn't include witness tx
            assert (tmpl['sizelimit'] == 2000000)
            assert ('weightlimit' not in tmpl)
            assert (tmpl['sigoplimit'] == 20000)
            assert (tmpl['transactions'][0]['hash'] == txid)
            assert (tmpl['transactions'][0]['sigops'] == 2)
            assert (('!segwit' in tmpl['rules'])
                    or ('segwit' not in tmpl['rules']))
        except JSONRPCException:
            # This is an acceptable outcome
            pass

        print(
            "Verify behaviour of importaddress, addwitnessaddress and listunspent"
        )

        # Some public keys to be used later
        pubkeys = [
            "0363D44AABD0F1699138239DF2F042C3282C0671CC7A76826A55C8203D90E39242",  # cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb
            "02D3E626B3E616FC8662B489C123349FECBFC611E778E5BE739B257EAE4721E5BF",  # cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97
            "04A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538A62F5BD8EC85C2477F39650BD391EA6250207065B2A81DA8B009FC891E898F0E",  # 91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV
            "02A47F2CBCEFFA7B9BCDA184E7D5668D3DA6F9079AD41E422FA5FD7B2D458F2538",  # cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd
            "036722F784214129FEB9E8129D626324F3F6716555B603FFE8300BBCB882151228",  # cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66
            "0266A8396EE936BF6D99D17920DB21C6C7B1AB14C639D5CD72B300297E416FD2EC",  # cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K
            "0450A38BD7F0AC212FEBA77354A9B036A32E0F7C81FC4E0C5ADCA7C549C4505D2522458C2D9AE3CEFD684E039194B72C8A10F9CB9D4764AB26FCC2718D421D3B84",  # 92h2XPssjBpsJN5CqSP7v9a7cf2kgDunBC6PDFwJHMACM1rrVBJ
        ]

        # Import a compressed key and an uncompressed key, generate some multisig addresses
        self.nodes[0].importprivkey(
            "92e6XLo5jVAVwrQKPNTs93oQco8f8sDNBcpv73Dsrs397fQtFQn")
        uncompressed_spendable_address = [
            convert_btc_address_to_mmchain(
                "mvozP4UwyGD2mGZU4D2eMvMLPB9WkMmMQu")
        ]
        self.nodes[0].importprivkey(
            "cNC8eQ5dg3mFAVePDX4ddmPYpPbw41r9bm2jd1nLJT77e6RrzTRR")
        compressed_spendable_address = [
            convert_btc_address_to_mmchain(
                "mmWQubrDomqpgSYekvsU7HWEVjLFHAakLe")
        ]
        assert ((self.nodes[0].validateaddress(
            uncompressed_spendable_address[0])['iscompressed'] == False))
        assert ((self.nodes[0].validateaddress(
            compressed_spendable_address[0])['iscompressed'] == True))

        self.nodes[0].importpubkey(pubkeys[0])
        compressed_solvable_address = [key_to_p2pkh(pubkeys[0])]
        self.nodes[0].importpubkey(pubkeys[1])
        compressed_solvable_address.append(key_to_p2pkh(pubkeys[1]))
        self.nodes[0].importpubkey(pubkeys[2])
        uncompressed_solvable_address = [key_to_p2pkh(pubkeys[2])]

        spendable_anytime = [
        ]  # These outputs should be seen anytime after importprivkey and addmultisigaddress
        spendable_after_importaddress = [
        ]  # These outputs should be seen after importaddress
        solvable_after_importaddress = [
        ]  # These outputs should be seen after importaddress but not spendable
        unsolvable_after_importaddress = [
        ]  # These outputs should be unsolvable after importaddress
        solvable_anytime = [
        ]  # These outputs should be solvable after importpubkey
        unseen_anytime = []  # These outputs should never be seen

        uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(
            2, [
                uncompressed_spendable_address[0],
                compressed_spendable_address[0]
            ]))
        uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(
            2, [
                uncompressed_spendable_address[0],
                uncompressed_spendable_address[0]
            ]))
        compressed_spendable_address.append(self.nodes[0].addmultisigaddress(
            2,
            [compressed_spendable_address[0], compressed_spendable_address[0]
             ]))
        uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(
            2, [
                compressed_spendable_address[0],
                uncompressed_solvable_address[0]
            ]))
        compressed_solvable_address.append(self.nodes[0].addmultisigaddress(
            2,
            [compressed_spendable_address[0], compressed_solvable_address[0]]))
        compressed_solvable_address.append(self.nodes[0].addmultisigaddress(
            2,
            [compressed_solvable_address[0], compressed_solvable_address[1]]))
        unknown_address = [
            convert_btc_address_to_mmchain(
                "mtKKyoHabkk6e4ppT7NaM7THqPUt7AzPrT"),
            convert_btc_address_to_mmchain(
                "2NDP3jLWAFT8NDAiUa9qiE6oBt2awmMq7Dx")
        ]

        # Test multisig_without_privkey
        # We have 2 public keys without private keys, use addmultisigaddress to add to wallet.
        # Money sent to P2SH of multisig of this should only be seen after importaddress with the BASE58 P2SH address.

        multisig_without_privkey_address = self.nodes[0].addmultisigaddress(
            2, [pubkeys[3], pubkeys[4]])
        script = CScript([
            OP_2,
            hex_str_to_bytes(pubkeys[3]),
            hex_str_to_bytes(pubkeys[4]), OP_2, OP_CHECKMULTISIG
        ])
        solvable_after_importaddress.append(
            CScript([OP_HASH160, hash160(script), OP_EQUAL]))

        for i in compressed_spendable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                [bare, p2sh, p2wsh,
                 p2sh_p2wsh] = self.p2sh_address_to_script(v)
                # bare and p2sh multisig with compressed keys should always be spendable
                spendable_anytime.extend([bare, p2sh])
                # P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after direct importaddress
                spendable_after_importaddress.extend([p2wsh, p2sh_p2wsh])
            else:
                [
                    p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh,
                    p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ] = self.p2pkh_address_to_script(v)
                # normal P2PKH and P2PK with compressed keys should always be spendable
                spendable_anytime.extend([p2pkh, p2pk])
                # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are spendable after direct importaddress
                spendable_after_importaddress.extend([
                    p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk,
                    p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ])

        for i in uncompressed_spendable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                [bare, p2sh, p2wsh,
                 p2sh_p2wsh] = self.p2sh_address_to_script(v)
                # bare and p2sh multisig with uncompressed keys should always be spendable
                spendable_anytime.extend([bare, p2sh])
                # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
                unseen_anytime.extend([p2wsh, p2sh_p2wsh])
            else:
                [
                    p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh,
                    p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ] = self.p2pkh_address_to_script(v)
                # normal P2PKH and P2PK with uncompressed keys should always be spendable
                spendable_anytime.extend([p2pkh, p2pk])
                # P2SH_P2PK and P2SH_P2PKH are spendable after direct importaddress
                spendable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh])
                # witness with uncompressed keys are never seen
                unseen_anytime.extend([
                    p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh,
                    p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ])

        for i in compressed_solvable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                # Multisig without private is not seen after addmultisigaddress, but seen after importaddress
                [bare, p2sh, p2wsh,
                 p2sh_p2wsh] = self.p2sh_address_to_script(v)
                solvable_after_importaddress.extend(
                    [bare, p2sh, p2wsh, p2sh_p2wsh])
            else:
                [
                    p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh,
                    p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ] = self.p2pkh_address_to_script(v)
                # normal P2PKH and P2PK with compressed keys should always be seen
                solvable_anytime.extend([p2pkh, p2pk])
                # P2SH_P2PK, P2SH_P2PKH, and witness with compressed keys are seen after direct importaddress
                solvable_after_importaddress.extend([
                    p2wpkh, p2sh_p2wpkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk,
                    p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ])

        for i in uncompressed_solvable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                [bare, p2sh, p2wsh,
                 p2sh_p2wsh] = self.p2sh_address_to_script(v)
                # Base uncompressed multisig without private is not seen after addmultisigaddress, but seen after importaddress
                solvable_after_importaddress.extend([bare, p2sh])
                # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
                unseen_anytime.extend([p2wsh, p2sh_p2wsh])
            else:
                [
                    p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh,
                    p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ] = self.p2pkh_address_to_script(v)
                # normal P2PKH and P2PK with uncompressed keys should always be seen
                solvable_anytime.extend([p2pkh, p2pk])
                # P2SH_P2PK, P2SH_P2PKH with uncompressed keys are seen after direct importaddress
                solvable_after_importaddress.extend([p2sh_p2pk, p2sh_p2pkh])
                # witness with uncompressed keys are never seen
                unseen_anytime.extend([
                    p2wpkh, p2sh_p2wpkh, p2wsh_p2pk, p2wsh_p2pkh,
                    p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ])

        op1 = CScript([OP_1])
        op0 = CScript([OP_0])
        # 2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe is the P2SH(P2PKH) version of mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V
        unsolvable_address = [
            convert_btc_address_to_mmchain(
                "mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V"),
            convert_btc_address_to_mmchain(
                "2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe"),
            script_to_p2sh(op1),
            script_to_p2sh(op0)
        ]
        unsolvable_address_key = hex_str_to_bytes(
            "02341AEC7587A51CDE5279E0630A531AEA2615A9F80B17E8D9376327BAEAA59E3D"
        )
        unsolvablep2pkh = CScript([
            OP_DUP, OP_HASH160,
            hash160(unsolvable_address_key), OP_EQUALVERIFY, OP_CHECKSIG
        ])
        unsolvablep2wshp2pkh = CScript([OP_0, sha256(unsolvablep2pkh)])
        p2shop0 = CScript([OP_HASH160, hash160(op0), OP_EQUAL])
        p2wshop1 = CScript([OP_0, sha256(op1)])
        unsolvable_after_importaddress.append(unsolvablep2pkh)
        unsolvable_after_importaddress.append(unsolvablep2wshp2pkh)
        unsolvable_after_importaddress.append(
            op1)  # OP_1 will be imported as script
        unsolvable_after_importaddress.append(p2wshop1)
        unseen_anytime.append(
            op0
        )  # OP_0 will be imported as P2SH address with no script provided
        unsolvable_after_importaddress.append(p2shop0)

        spendable_txid = []
        solvable_txid = []
        spendable_txid.append(
            self.mine_and_test_listunspent(spendable_anytime, 2))
        solvable_txid.append(
            self.mine_and_test_listunspent(solvable_anytime, 1))
        self.mine_and_test_listunspent(
            spendable_after_importaddress + solvable_after_importaddress +
            unseen_anytime + unsolvable_after_importaddress, 0)

        importlist = []
        for i in compressed_spendable_address + uncompressed_spendable_address + compressed_solvable_address + uncompressed_solvable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                bare = hex_str_to_bytes(v['hex'])
                importlist.append(bytes_to_hex_str(bare))
                importlist.append(
                    bytes_to_hex_str(CScript([OP_0, sha256(bare)])))
            else:
                pubkey = hex_str_to_bytes(v['pubkey'])
                p2pk = CScript([pubkey, OP_CHECKSIG])
                p2pkh = CScript([
                    OP_DUP, OP_HASH160,
                    hash160(pubkey), OP_EQUALVERIFY, OP_CHECKSIG
                ])
                importlist.append(bytes_to_hex_str(p2pk))
                importlist.append(bytes_to_hex_str(p2pkh))
                importlist.append(
                    bytes_to_hex_str(CScript([OP_0, hash160(pubkey)])))
                importlist.append(
                    bytes_to_hex_str(CScript([OP_0, sha256(p2pk)])))
                importlist.append(
                    bytes_to_hex_str(CScript([OP_0, sha256(p2pkh)])))

        importlist.append(bytes_to_hex_str(unsolvablep2pkh))
        importlist.append(bytes_to_hex_str(unsolvablep2wshp2pkh))
        importlist.append(bytes_to_hex_str(op1))
        importlist.append(bytes_to_hex_str(p2wshop1))

        for i in importlist:
            try:
                self.nodes[0].importaddress(i, "", False, True)
            except JSONRPCException as exp:
                assert_equal(
                    exp.error["message"],
                    "The wallet already contains the private key for this address or script"
                )

        self.nodes[0].importaddress(
            script_to_p2sh(op0))  # import OP_0 as address only
        self.nodes[0].importaddress(
            multisig_without_privkey_address)  # Test multisig_without_privkey

        spendable_txid.append(
            self.mine_and_test_listunspent(
                spendable_anytime + spendable_after_importaddress, 2))
        solvable_txid.append(
            self.mine_and_test_listunspent(
                solvable_anytime + solvable_after_importaddress, 1))
        self.mine_and_test_listunspent(unsolvable_after_importaddress, 1)
        self.mine_and_test_listunspent(unseen_anytime, 0)

        # addwitnessaddress should refuse to return a witness address if an uncompressed key is used or the address is
        # not in the wallet
        # note that no witness address should be returned by unsolvable addresses
        # the multisig_without_privkey_address will fail because its keys were not added with importpubkey
        for i in uncompressed_spendable_address + uncompressed_solvable_address + unknown_address + unsolvable_address + [
                multisig_without_privkey_address
        ]:
            try:
                self.nodes[0].addwitnessaddress(i)
            except JSONRPCException as exp:
                assert_equal(
                    exp.error["message"],
                    "Public key or redeemscript not known to wallet, or the key is uncompressed"
                )
            else:
                assert (False)

        for i in compressed_spendable_address + compressed_solvable_address:
            witaddress = self.nodes[0].addwitnessaddress(i)
            # addwitnessaddress should return the same address if it is a known P2SH-witness address
            assert_equal(witaddress,
                         self.nodes[0].addwitnessaddress(witaddress))

        spendable_txid.append(
            self.mine_and_test_listunspent(
                spendable_anytime + spendable_after_importaddress, 2))
        solvable_txid.append(
            self.mine_and_test_listunspent(
                solvable_anytime + solvable_after_importaddress, 1))
        self.mine_and_test_listunspent(unsolvable_after_importaddress, 1)
        self.mine_and_test_listunspent(unseen_anytime, 0)

        # Repeat some tests. This time we don't add witness scripts with importaddress
        # Import a compressed key and an uncompressed key, generate some multisig addresses
        self.nodes[0].importprivkey(
            "927pw6RW8ZekycnXqBQ2JS5nPyo1yRfGNN8oq74HeddWSpafDJH")
        uncompressed_spendable_address = [
            convert_btc_address_to_mmchain(
                "mguN2vNSCEUh6rJaXoAVwY3YZwZvEmf5xi")
        ]
        self.nodes[0].importprivkey(
            "cMcrXaaUC48ZKpcyydfFo8PxHAjpsYLhdsp6nmtB3E2ER9UUHWnw")
        compressed_spendable_address = [
            convert_btc_address_to_mmchain(
                "n1UNmpmbVUJ9ytXYXiurmGPQ3TRrXqPWKL")
        ]

        self.nodes[0].importpubkey(pubkeys[5])
        compressed_solvable_address = [key_to_p2pkh(pubkeys[5])]
        self.nodes[0].importpubkey(pubkeys[6])
        uncompressed_solvable_address = [key_to_p2pkh(pubkeys[6])]

        spendable_after_addwitnessaddress = [
        ]  # These outputs should be seen after importaddress
        solvable_after_addwitnessaddress = [
        ]  # These outputs should be seen after importaddress but not spendable
        unseen_anytime = []  # These outputs should never be seen

        uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(
            2, [
                uncompressed_spendable_address[0],
                compressed_spendable_address[0]
            ]))
        uncompressed_spendable_address.append(self.nodes[0].addmultisigaddress(
            2, [
                uncompressed_spendable_address[0],
                uncompressed_spendable_address[0]
            ]))
        compressed_spendable_address.append(self.nodes[0].addmultisigaddress(
            2,
            [compressed_spendable_address[0], compressed_spendable_address[0]
             ]))
        uncompressed_solvable_address.append(self.nodes[0].addmultisigaddress(
            2,
            [compressed_solvable_address[0], uncompressed_solvable_address[0]
             ]))
        compressed_solvable_address.append(self.nodes[0].addmultisigaddress(
            2,
            [compressed_spendable_address[0], compressed_solvable_address[0]]))

        premature_witaddress = []

        for i in compressed_spendable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                [bare, p2sh, p2wsh,
                 p2sh_p2wsh] = self.p2sh_address_to_script(v)
                # P2WSH and P2SH(P2WSH) multisig with compressed keys are spendable after addwitnessaddress
                spendable_after_addwitnessaddress.extend([p2wsh, p2sh_p2wsh])
                premature_witaddress.append(script_to_p2sh(p2wsh))
            else:
                [
                    p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh,
                    p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ] = self.p2pkh_address_to_script(v)
                # P2WPKH, P2SH_P2WPKH are spendable after addwitnessaddress
                spendable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh])
                premature_witaddress.append(script_to_p2sh(p2wpkh))

        for i in uncompressed_spendable_address + uncompressed_solvable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                [bare, p2sh, p2wsh,
                 p2sh_p2wsh] = self.p2sh_address_to_script(v)
                # P2WSH and P2SH(P2WSH) multisig with uncompressed keys are never seen
                unseen_anytime.extend([p2wsh, p2sh_p2wsh])
            else:
                [
                    p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh,
                    p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ] = self.p2pkh_address_to_script(v)
                # P2WPKH, P2SH_P2WPKH with uncompressed keys are never seen
                unseen_anytime.extend([p2wpkh, p2sh_p2wpkh])

        for i in compressed_solvable_address:
            v = self.nodes[0].validateaddress(i)
            if (v['isscript']):
                # P2WSH multisig without private key are seen after addwitnessaddress
                [bare, p2sh, p2wsh,
                 p2sh_p2wsh] = self.p2sh_address_to_script(v)
                solvable_after_addwitnessaddress.extend([p2wsh, p2sh_p2wsh])
                premature_witaddress.append(script_to_p2sh(p2wsh))
            else:
                [
                    p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh,
                    p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh
                ] = self.p2pkh_address_to_script(v)
                # P2SH_P2PK, P2SH_P2PKH with compressed keys are seen after addwitnessaddress
                solvable_after_addwitnessaddress.extend([p2wpkh, p2sh_p2wpkh])
                premature_witaddress.append(script_to_p2sh(p2wpkh))

        self.mine_and_test_listunspent(
            spendable_after_addwitnessaddress +
            solvable_after_addwitnessaddress + unseen_anytime, 0)

        # addwitnessaddress should refuse to return a witness address if an uncompressed key is used
        # note that a multisig address returned by addmultisigaddress is not solvable until it is added with importaddress
        # premature_witaddress are not accepted until the script is added with addwitnessaddress first
        for i in uncompressed_spendable_address + uncompressed_solvable_address + premature_witaddress + [
                compressed_solvable_address[1]
        ]:
            try:
                self.nodes[0].addwitnessaddress(i)
            except JSONRPCException as exp:
                assert_equal(
                    exp.error["message"],
                    "Public key or redeemscript not known to wallet, or the key is uncompressed"
                )
            else:
                assert (False)

        # after importaddress it should pass addwitnessaddress
        v = self.nodes[0].validateaddress(compressed_solvable_address[1])
        self.nodes[0].importaddress(v['hex'], "", False, True)
        for i in compressed_spendable_address + compressed_solvable_address + premature_witaddress:
            witaddress = self.nodes[0].addwitnessaddress(i)
            assert_equal(witaddress,
                         self.nodes[0].addwitnessaddress(witaddress))

        spendable_txid.append(
            self.mine_and_test_listunspent(spendable_after_addwitnessaddress,
                                           2))
        solvable_txid.append(
            self.mine_and_test_listunspent(solvable_after_addwitnessaddress,
                                           1))
        self.mine_and_test_listunspent(unseen_anytime, 0)

        # Check that spendable outputs are really spendable
        self.create_and_mine_tx_from_txids(spendable_txid)

        # import all the private keys so solvable addresses become spendable
        self.nodes[0].importprivkey(
            "cPiM8Ub4heR9NBYmgVzJQiUH1if44GSBGiqaeJySuL2BKxubvgwb")
        self.nodes[0].importprivkey(
            "cPpAdHaD6VoYbW78kveN2bsvb45Q7G5PhaPApVUGwvF8VQ9brD97")
        self.nodes[0].importprivkey(
            "91zqCU5B9sdWxzMt1ca3VzbtVm2YM6Hi5Rxn4UDtxEaN9C9nzXV")
        self.nodes[0].importprivkey(
            "cPQFjcVRpAUBG8BA9hzr2yEzHwKoMgLkJZBBtK9vJnvGJgMjzTbd")
        self.nodes[0].importprivkey(
            "cQGtcm34xiLjB1v7bkRa4V3aAc9tS2UTuBZ1UnZGeSeNy627fN66")
        self.nodes[0].importprivkey(
            "cTW5mR5M45vHxXkeChZdtSPozrFwFgmEvTNnanCW6wrqwaCZ1X7K")
        self.create_and_mine_tx_from_txids(solvable_txid)
Example #6
0
    def script_verification_error_test(self):
        """Creates and signs a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script.

        Expected results:

        3) The transaction has no complete set of signatures
        4) Two script verification errors occurred
        5) Script verification errors have certain properties ("txid", "vout", "scriptSig", "sequence", "error")
        6) The verification errors refer to the invalid (vin 1) and missing input (vin 2)"""
        privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N']

        inputs = [
            # Valid pay-to-pubkey script
            {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0},
            # Invalid script
            {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7},
            # Missing scriptPubKey
            {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 1},
        ]

        scripts = [
            # Valid pay-to-pubkey script
            {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
             'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
            # Invalid script
            {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7,
             'scriptPubKey': 'badbadbadbad'}
        ]

        outputs = {convert_btc_address_to_mmchain('mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB'): 0.1}

        rawTx = self.nodes[0].createrawtransaction(inputs, outputs)

        # Make sure decoderawtransaction is at least marginally sane
        decodedRawTx = self.nodes[0].decoderawtransaction(rawTx)
        for i, inp in enumerate(inputs):
            assert_equal(decodedRawTx["vin"][i]["txid"], inp["txid"])
            assert_equal(decodedRawTx["vin"][i]["vout"], inp["vout"])

        # Make sure decoderawtransaction throws if there is extra data
        assert_raises(JSONRPCException, self.nodes[0].decoderawtransaction, rawTx + "00")

        rawTxSigned = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys)

        # 3) The transaction has no complete set of signatures
        assert 'complete' in rawTxSigned
        assert_equal(rawTxSigned['complete'], False)

        # 4) Two script verification errors occurred
        assert 'errors' in rawTxSigned
        assert_equal(len(rawTxSigned['errors']), 2)

        # 5) Script verification errors have certain properties
        assert 'txid' in rawTxSigned['errors'][0]
        assert 'vout' in rawTxSigned['errors'][0]
        assert 'scriptSig' in rawTxSigned['errors'][0]
        assert 'sequence' in rawTxSigned['errors'][0]
        assert 'error' in rawTxSigned['errors'][0]

        # 6) The verification errors refer to the invalid (vin 1) and missing input (vin 2)
        assert_equal(rawTxSigned['errors'][0]['txid'], inputs[1]['txid'])
        assert_equal(rawTxSigned['errors'][0]['vout'], inputs[1]['vout'])
        assert_equal(rawTxSigned['errors'][1]['txid'], inputs[2]['txid'])
        assert_equal(rawTxSigned['errors'][1]['vout'], inputs[2]['vout'])
Example #7
0
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

#
# Test fee estimation code
#

from collections import OrderedDict
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.address import convert_btc_address_to_mmchain

# Construct 2 trivial P2SH's and the ScriptSigs that spend them
# So we can create many many transactions without needing to spend
# time signing.
P2SH_1 = convert_btc_address_to_mmchain("2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2") # P2SH of "OP_1 OP_DROP"
P2SH_2 = convert_btc_address_to_mmchain("2NBdpwq8Aoo1EEKEXPNrKvr5xQr3M9UfcZA") # P2SH of "OP_2 OP_DROP"
# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2
# 4 bytes of OP_TRUE and push 2-byte redeem script of "OP_1 OP_DROP" or "OP_2 OP_DROP"
SCRIPT_SIG = ["0451025175", "0451025275"]

def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
    '''
    Create and send a transaction with a random fee.
    The transaction pays to a trivial P2SH script, and assumes that its inputs
    are of the same form.
    The function takes a list of confirmed outputs and unconfirmed outputs
    and attempts to use the confirmed list first for its inputs.
    It adds the newly created outputs to the unconfirmed list.
    Returns (raw transaction, fee)
    '''