Beispiel #1
0
    def test_invalid_args(self, electrum_client):
        from test_framework.connectrum.exc import ElectrumErrorResponse
        error_code = "-32602"

        hash_param_methods = ("blockchain.scripthash.get_balance",
                              "blockchain.scripthash.get_history",
                              "blockchain.scripthash.listunspent")

        for method in hash_param_methods:
            assert_raises(ElectrumErrorResponse, electrum_client.call, method,
                          "invalidhash")

            try:
                electrum_client.call(method, "invalidhash")
            except Exception as e:
                print("ERROR:" + str(e))
                assert error_code in str(e)

        # invalid tx
        try:
            tx = CTransaction()
            tx.calc_sha256()
            tx.vin = [CTxIn(COutPoint(0xbeef, 1))]
            electrum_client.call("blockchain.transaction.broadcast", ToHex(tx))
        except Exception as e:
            print("ERROR: " + str(e))
            assert error_code in str(e)
    def _zmq_test(self):
        """Note that this function is very picky about the exact order of generated ZMQ announcements.
           However, this order does not actually matter.  So bitcoind code changes my break this test.
        """
        num_blocks = 5
        logging.info(
            "Generate {0} blocks (and {0} coinbase txes)".format(num_blocks))

        # DS does not support P2PK so make sure there's a P2PKH in the wallet
        addr = self.nodes[0].getnewaddress()
        fundTx = self.nodes[0].sendtoaddress(addr, 10)
        # Notify of new tx
        zmqNotif = self.hashtx.receive().hex()
        assert fundTx == zmqNotif
        zmqNotif = self.rawtx.receive()

        genhashes = self.nodes[0].generate(1)
        # notify tx 1
        zmqNotif1 = self.hashtx.receive().hex()
        assert fundTx == zmqNotif1
        zmqNotif1r = self.rawtx.receive()
        # notify coinbase
        zmqNotif2 = self.hashtx.receive().hex()
        zmqNotif2r = self.rawtx.receive()
        assert b"/EB32/AD12" in zmqNotif2r
        # notify tx 1 again
        zmqNotif = self.hashtx.receive().hex()
        assert fundTx == zmqNotif
        zmqNotif = self.rawtx.receive()

        # notify the block
        h = self.hashblock.receive().hex()
        b = self.rawblock.receive()

        genhashes = self.nodes[0].generate(num_blocks)

        self.sync_all()

        for x in range(num_blocks):
            # Should receive the coinbase txid.
            txid = self.hashtx.receive()
            # Should receive the coinbase raw transaction.
            hex = self.rawtx.receive()
            tx = CTransaction()
            tx.deserialize(BytesIO(hex))
            tx.calc_sha256()
            assert_equal(tx.hash, txid.hex())


            # Should receive the generated block hash.
            hash = self.hashblock.receive().hex()
            assert_equal(genhashes[x], hash)
            # The block should only have the coinbase txid.
            assert_equal([txid.hex()], self.nodes[1].getblock(hash)["tx"])

            # Should receive the generated raw block.
            block = self.rawblock.receive()
            assert_equal(genhashes[x], hash256(block[:80])[::-1].hex())

        logging.info("Wait for tx from second node")
        payment_txid = self.nodes[1].sendtoaddress(
            self.nodes[0].getnewaddress(), 1.0)
        self.sync_all()

        # Should receive the broadcasted txid.
        txid = self.hashtx.receive()
        assert_equal(payment_txid, txid.hex())

        # Should receive the broadcasted raw transaction.
        hex = self.rawtx.receive()
        assert_equal(payment_txid, hash256(hex)[::-1].hex())

        if 1: # Send 2 transactions that double spend each other

            # If these unsubscribes fail, then you will get an assertion that a zmq topic is not correct
            self.hashtx.unsubscribe()
            self.rawtx.unsubscribe()

            wallet = self.nodes[0].listunspent()
            walletp2pkh = list(filter(lambda x : len(x["scriptPubKey"]) != 70, wallet)) # Find an input that is not P2PK
            t = walletp2pkh.pop()
            inputs = []
            inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
            outputs = { self.nodes[1].getnewaddress() : t["amount"] }

            rawtx   = self.nodes[0].createrawtransaction(inputs, outputs)
            rawtx   = self.nodes[0].signrawtransaction(rawtx)
            mpTx = self.nodes[0].getmempoolinfo()["size"]
            try:
                hashTxToDoubleSpend   = self.nodes[1].sendrawtransaction(rawtx['hex'])
            except JSONRPCException as e:
                print(e.error['message'])
                assert False
                self.sync_all()

            outputs = { self.nodes[1].getnewaddress() : t["amount"] }
            rawtx   = self.nodes[0].createrawtransaction(inputs, outputs)
            rawtx   = self.nodes[0].signrawtransaction(rawtx)
            waitFor(30, lambda: self.nodes[0].getmempoolinfo()["size"] > mpTx)  # make sure the original tx propagated in time
            try:
                hashtx   = self.nodes[0].sendrawtransaction(rawtx['hex'])
            except JSONRPCException as e:
                assert("txn-mempool-conflict" in e.error['message'])
            else:
                assert(False)
                self.sync_all()

            # since I unsubscribed from these I don't need to load them
            #self.hashtx.receive()
            #self.rawtx.receive()

            # Should receive hash of a double spend proof.
            dsTxHash = self.hashds.receive()
            assert hashTxToDoubleSpend == dsTxHash.hex()
            ds  = self.rawds.receive()
            assert len(ds) > 0