Esempio n. 1
0
 def test_addr_script_hash(self):
     pairs = [
         (
             "52fdfc072182654f163f5f0f9a621d729566c74d",
             "Dcf2QjJ1pSnLwthhw1cwE55MVZNQVXDZWQT",
         ),
         (
             "10037c4d7bbb0407d1e2c64981855ad8681d0d86",
             "DcYvG3fPxHDZ5pzW8nj4rcYq5kM9XFxXpUy",
         ),
         (
             "d1e91e00167939cb6694d2c422acd208a0072939",
             "DcrbVYmhm5yX9mw9qdwUVWw6psUhPGrQJsT",
         ),
         (
             "487f6999eb9d18a44784045d87f3c67cf22746e9",
             "Dce4vLzzENaZT7D2Wq5crRZ4VwfYMDMWkD9",
         ),
         (
             "95af5a25367951baa2ff6cd471c483f15fb90bad",
             "Dcm73og7Hn9PigaNu59dHgKnNSP1myCQ39t",
         ),
     ]
     for scriptHash, addrStr in pairs:
         addr = addrlib.AddressScriptHash(ByteArray(scriptHash), mainnet)
         assert addr.string() == addrStr
Esempio n. 2
0
    def test_main(self, monkeypatch):
        """
        Test account functionality.
        """
        # Set up globals for test.
        monkeypatch.setattr(account, "DefaultGapLimit", 2)

        db = KeyValueDatabase(":memory:").child("tmp")
        acct = self.newAccount(db)
        acct.unlock(self.cryptoKey)
        acct.generateGapAddresses()
        for _ in range(20):
            acct.nextExternalAddress()
        satoshis = int(round(5 * 1e8))
        txHash = rando.newHash()
        txid = reversed(txHash).hex()
        vout = 2
        address = acct.nextExternalAddress()

        utxo = account.UTXO(
            address=address,
            txHash=txHash,
            vout=vout,
            scriptPubKey=ByteArray(0),
            satoshis=satoshis,
            maturity=1,
        )

        # A helper function to get the current utxo count.
        utxocount = lambda: len(list(acct.utxoscan()))

        # Add the utxo
        acct.addUTXO(utxo)
        # Check the count and balance categories.
        assert utxocount() == 1
        assert acct.calcBalance(1).total == satoshis
        assert acct.calcBalance(1).available == satoshis
        assert acct.calcBalance(0).available == 0
        # Helper functions.
        assert acct.caresAboutTxid(txid)
        assert not acct.caresAboutTxid("")
        acct.addUTXO(utxo)
        assert utxocount() == 1
        acct.spendUTXO(utxo)
        assert utxocount() == 0

        b = acct.serialize()
        reAcct = account.Account.unblob(b.b)

        assert acct.pubKeyEncrypted == reAcct.pubKeyEncrypted
        assert acct.privKeyEncrypted == reAcct.privKeyEncrypted
        assert acct.name == reAcct.name
        assert acct.coinID == reAcct.coinID
        assert acct.netID == reAcct.netID
        assert acct.gapLimit == reAcct.gapLimit
        assert acct.cursorExt == reAcct.cursorExt
        assert acct.cursorInt == reAcct.cursorInt
        assert acct.gapLimit == reAcct.gapLimit

        # Create a faux blockchain for the account.
        class Blockchain:
            txidsForAddr = lambda addr: []
            UTXOs = lambda addrs: []
            tipHeight = 5

        acct.blockchain = Blockchain

        class Signals:
            b = None

            @classmethod
            def balance(cls, b):
                cls.b = b

        acct.signals = Signals

        # Add a txid for this first address
        txid = rando.newHash().hex()
        zerothAddr = acct.externalAddresses[0]
        acct.addTxid(zerothAddr, txid)
        # Add a voting service provider
        vspKey = rando.newKey().hex()
        ticketAddr = "ticketAddr"
        pi = PurchaseInfo("addr", 1.0, ByteArray(b"scripthashscript"),
                          ticketAddr, 1, 0, 2)
        vsp = VotingServiceProvider("https://myvsp.com", vspKey,
                                    nets.mainnet.Name, pi)
        with pytest.raises(DecredError):
            acct.setPool(None)
        acct.setPool(vsp)
        acct.setNewPool(vsp)
        # Add UTXOs
        utxos = [account.UTXO.parse(u) for u in self.dcrdataUTXOs]
        acct.resolveUTXOs(utxos)
        ticketStats = acct.ticketStats()
        assert ticketStats.count == 0
        assert ticketStats.value == 0

        # Check that the addresses txid and the vsp load from the database.
        acct.txs.clear()
        acct.stakePools.clear()
        acct.utxos.clear()
        assert acct.stakePool() is None
        acct.load(db, Blockchain, Signals)
        assert zerothAddr in acct.txs
        assert len(acct.txs[zerothAddr]) == 1
        assert acct.txs[zerothAddr][0] == txid
        assert len(acct.stakePools) == 1
        assert acct.stakePool().apiKey == vspKey
        assert acct.calcBalance().available == self.utxoTotal
        assert len(acct.getUTXOs(self.utxoTotal)[0]) == 2
        assert len(acct.getUTXOs(self.utxoTotal, lambda u: False)[0]) == 0
        assert acct.lastSeen(acct.externalAddresses, -1) == 0
        branch, idx = acct.branchAndIndex(zerothAddr)
        assert branch == account.EXTERNAL_BRANCH
        assert idx == 0
        branch, idx = acct.branchAndIndex(acct.internalAddresses[0])
        assert branch == account.INTERNAL_BRANCH
        assert idx == 0
        checkKey = acct.privKey.child(account.EXTERNAL_BRANCH).child(0).key
        with pytest.raises(DecredError):
            acct.privKeyForAddress("")
        assert acct.privKeyForAddress(zerothAddr).key == checkKey
        ticketAddrs = acct.addTicketAddresses([])
        assert len(ticketAddrs) == 1
        assert ticketAddrs[0] == ticketAddr
        assert acct.hasPool()

        # Exercise setNode
        acct.setNode(1)
        assert acct.node == 1

        # Add a coinbase transaction output to the account.
        coinbase = newCoinbaseTx()
        cbUTXO = account.UTXO("addr",
                              ByteArray(b"id"),
                              1,
                              height=5,
                              satoshis=int(1e8))
        coinbase.addTxOut(msgtx.TxOut(int(1e8)))
        coinbaseID = coinbase.id()
        cbUTXO.txid = coinbaseID
        acct.addUTXO(cbUTXO)
        acct.addMempoolTx(coinbase)
        assert coinbaseID in acct.mempool
        # Send a block signal and have the transaction confirmed.
        sig = {"message": {"block": {"Tx": [{"TxID": coinbaseID}]}}}
        acct.blockchain.tipHeight = 5
        acct.blockchain.tx = lambda *a: coinbase
        acct.blockSignal(sig)
        assert coinbaseID not in acct.mempool
        assert cbUTXO.key() in acct.utxos
        maturity = 5 + nets.mainnet.CoinbaseMaturity
        assert acct.utxos[cbUTXO.key()].maturity == maturity
        assert acct.calcBalance(
            maturity).available == self.utxoTotal + cbUTXO.satoshis
        assert acct.calcBalance(0).available == self.utxoTotal
        acct.spendUTXOs([cbUTXO])
        assert acct.calcBalance(maturity).available == self.utxoTotal

        # make a ticket and a vote
        ticket = account.UTXO.parse(dcrdataUTXO)
        utxo.setTicketInfo(dcrdataTinfo)
        utxo.scriptPubKey = ticketScript
        utxo.parseScriptClass()
        acct.addUTXO(ticket)
        expVal = acct.calcBalance().available - ticket.satoshis
        voteTx = msgtx.MsgTx.new()
        voteTx.addTxIn(
            msgtx.TxIn(
                msgtx.OutPoint(reversed(ByteArray(ticket.txid)), ticket.vout,
                               0)))
        acct.blockchain.tx = lambda *a: voteTx
        acct.addressSignal(ticketAddr, "somehash")
        assert Signals.b.available == expVal

        # Detect a new utxo for the account.
        newVal = int(5e8)
        expVal = acct.calcBalance().available + newVal
        addr = acct.externalAddresses[1]
        a = addrlib.decodeAddress(addr, nets.mainnet)
        script = txscript.payToAddrScript(a)
        newTx = msgtx.MsgTx.new()
        op = msgtx.TxOut(newVal, script)
        newTx.addTxOut(op)
        acct.blockchain.tx = lambda *a: newTx
        utxo = account.UTXO(addr, ByteArray(b"txid"), 0, satoshis=newVal)
        acct.blockchain.txVout = lambda *a: utxo
        acct.addressSignal(addr, "somehash")
        assert Signals.b.available == expVal

        # test syncing. add a single output for external address #2
        acct.stakePool().getPurchaseInfo = lambda: None
        acct.stakePool().authorize = lambda a: True
        newVal = int(3e8)
        addr = acct.externalAddresses[2]
        a = addrlib.decodeAddress(addr, nets.mainnet)
        script = txscript.payToAddrScript(a)
        newTx = msgtx.MsgTx.new()
        op = msgtx.TxOut(newVal, script)
        newTx.addTxOut(op)
        utxo = account.UTXO(addr, ByteArray(b"txid"), 0, satoshis=newVal)

        def t4a(*a):
            acct.blockchain.txidsForAddr = lambda *a: []
            return [newTx.id()]

        acct.blockchain.txidsForAddr = t4a

        def utxos4a(*a):
            acct.blockchain.UTXOs = lambda *a: []
            return [utxo]

        acct.blockchain.UTXOs = utxos4a
        acct.blockchain.subscribeAddresses = lambda addrs, receiver: None
        acct.blockchain.subscribeBlocks = lambda a: None
        acct.sync()
        assert Signals.b.available == newVal

        # spend the utxo by sending it. Reusing newTx for convenience.
        changeVal = int(5e7)
        addr = acct.internalAddresses[0]
        change = account.UTXO(addr,
                              ByteArray(b"newtxid"),
                              0,
                              satoshis=changeVal)
        acct.blockchain.sendToAddress = lambda *a: (newTx, [utxo], [change])
        acct.sendToAddress(1, "recipient")
        assert Signals.b.available == changeVal

        # purchase some tickets. Reusing newTx for convenience again.
        ticket = account.UTXO.parse(dcrdataUTXO)
        ticket.setTicketInfo(dcrdataTinfo)
        ticket.scriptPubKey = ticketScript
        ticket.parseScriptClass()
        acct.blockchain.purchaseTickets = lambda *a: ([newTx, []], [],
                                                      [ticket])
        acct.signals.spentTickets = lambda: True
        acct.purchaseTickets(1, 1)
        assert Signals.b.total == changeVal + ticket.satoshis

        # revoke the ticket
        ticketTx = msgtx.MsgTx.new()
        op = msgtx.TxOut(ticket.satoshis, ticket.scriptPubKey)
        ticketTx.addTxOut(op)
        ticket.tinfo.status = "missed"
        redeemHash = addrlib.AddressScriptHash(
            txscript.extractStakeScriptHash(ticketScript, opcode.OP_SSTX),
            nets.mainnet,
        )
        acct.stakePool().purchaseInfo.ticketAddress = redeemHash.string()
        revoked = False

        def rev(*a):
            nonlocal revoked
            revoked = True

        acct.blockchain.tx = lambda *a: ticketTx
        acct.blockchain.revokeTicket = rev
        acct.revokeTickets()
        assert revoked
Esempio n. 3
0
def test_Client(dcrdConfig):
    if dcrdConfig is None:
        pytest.skip("did not locate a dcrd config file")
    rpcClient = rpc.Client(
        urlunsplit(("https", dcrdConfig["rpclisten"], "/", "", "")),
        dcrdConfig["rpcuser"],
        dcrdConfig["rpcpass"],
        dcrdConfig["rpccert"],
    )

    stringify = rpc.stringify
    assert stringify(ByteArray("face")) == "cefa"
    assert stringify([ByteArray("face"),
                      ByteArray("baadf00d")]) == ["cefa", "0df0adba"]
    assert stringify("face") == "face"
    assert stringify(["face", "baadf00d"]) == ["face", "baadf00d"]
    alist = [ByteArray("face"), "baadf00d", ByteArray("deadbeef")]
    alistReversed = ["cefa", "baadf00d", "efbeadde"]
    assert set(stringify((b for b in alist))) == set(
        (s for s in alistReversed))
    assert stringify([
        ByteArray("face"),
        (ByteArray("badd"), "d00d", ByteArray("babe")),
        [alist, [alist], [alist, alist, [alist]]],
        [ByteArray("feed"), ByteArray("1100")],
        set({
            "hey": ByteArray("1234"),
            "there": ByteArray("4321")
        }.keys()),
        ByteArray("baadf00d"),
    ]) == [
        "cefa",
        ("ddba", "d00d", "beba"),
        [
            ["cefa", "baadf00d", "efbeadde"],
            [["cefa", "baadf00d", "efbeadde"]],
            [
                ["cefa", "baadf00d", "efbeadde"],
                ["cefa", "baadf00d", "efbeadde"],
                [["cefa", "baadf00d", "efbeadde"]],
            ],
        ],
        ["edfe", "0011"],
        {"there", "hey"},
        "0df0adba",
    ]

    with pytest.raises(DecredError):
        rpcClient.call("no_such_method")

    assert rpcClient.addNode("127.0.0.1", "onetry") is None

    debugLevel = rpcClient.debugLevel("show")
    assert isinstance(debugLevel, str)

    debugLevel = rpcClient.debugLevel("info")
    assert debugLevel == "Done."

    estimateFee = rpcClient.estimateFee()
    assert isinstance(estimateFee, int)

    estimateSmartFee = rpcClient.estimateSmartFee(32)
    assert isinstance(estimateSmartFee, int)

    estimateStakeDiff = rpcClient.estimateStakeDiff(0)
    assert isinstance(estimateStakeDiff, rpc.EstimateStakeDiffResult)

    existsAddress = rpcClient.existsAddress(mainnetAddress)
    assert existsAddress

    existsAddress = rpcClient.existsAddress(cookedAddress1)
    assert not existsAddress

    existsAddresses = rpcClient.existsAddresses([
        cookedAddress1,
        cookedAddress2,
        mainnetAddress,
        cookedAddress2,
        cookedAddress1,
        cookedAddress2,
        mainnetAddress,
    ])
    assert existsAddresses == [False, False, True, False, False, False, True]

    liveTickets = rpcClient.liveTickets()
    assert isinstance(liveTickets, list)

    aTicket = liveTickets[0]

    for ticket in liveTickets:
        getRawTransaction = rpcClient.getRawTransaction(ticket)

        script = getRawTransaction.txOut[0].pkScript

        if txscript.extractStakeScriptHash(script, opcode.OP_SSTX):
            decodeScript = rpcClient.decodeScript(script)
            assert isinstance(decodeScript, rpc.DecodeScriptResult)
            break

    else:
        raise RuntimeError("did not find a suitable script to decode")

    existsExpiredTickets = rpcClient.existsExpiredTickets([aTicket, aTicket])
    assert existsExpiredTickets == [False, False]

    bestBlock = rpcClient.getBestBlock()
    assert isinstance(bestBlock, rpc.GetBestBlockResult)

    blockchainInfo = rpcClient.getBlockchainInfo()
    assert isinstance(blockchainInfo, rpc.GetBlockChainInfoResult)

    getAddedNodeInfo = rpcClient.getAddedNodeInfo(True)
    assert isinstance(getAddedNodeInfo, list)

    getAddedNodeInfo = rpcClient.getAddedNodeInfo(False)
    assert isinstance(getAddedNodeInfo, list)

    getBestBlockHash = rpcClient.getBestBlockHash()
    assert isinstance(getBestBlockHash, ByteArray)

    getBlock = rpcClient.getBlock(blkHash414000, False)
    assert getBlock == blkHex414000

    getBlock = rpcClient.getBlock(blkHash414000)
    assert isinstance(getBlock, rpc.GetBlockVerboseResult)

    getBlock = rpcClient.getBlock(blkHash414000, True, True)
    assert isinstance(getBlock, rpc.GetBlockVerboseResult)

    getBlockCount = rpcClient.getBlockCount()
    assert isinstance(getBlockCount, int)

    getBlockHash = rpcClient.getBlockHash(0)
    assert getBlockHash == reversed(ByteArray(genesisHash))

    getBlockHeader = rpcClient.getBlockHeader(blkHash414000)
    assert isinstance(getBlockHeader, rpc.GetBlockHeaderVerboseResult)

    getBlockHeader = rpcClient.getBlockHeader(blkHash414000, False)
    assert isinstance(getBlockHeader, BlockHeader)

    getBlockSubsidy = rpcClient.getBlockSubsidy(414500, 5)
    assert isinstance(getBlockSubsidy, rpc.GetBlockSubsidyResult)

    getCFilter = rpcClient.getCFilter(blkHash414000, "extended")
    assert getCFilter == cFilter414000

    getCFilterHeader = rpcClient.getCFilterHeader(blkHash414000, "extended")
    assert getCFilterHeader == cFilterHeader414000

    getCFilterV2 = rpcClient.getCFilterV2(blkHash414000)
    assert isinstance(getCFilterV2, rpc.GetCFilterV2Result)

    getChainTips = rpcClient.getChainTips()
    assert isinstance(getChainTips[0], rpc.GetChainTipsResult)

    getCoinSupply = rpcClient.getCoinSupply()
    assert isinstance(getCoinSupply, int)

    getConnectionCount = rpcClient.getConnectionCount()
    assert isinstance(getConnectionCount, int)

    getCurrentNet = rpcClient.getCurrentNet()
    assert isinstance(getCurrentNet, int)

    getDifficulty = rpcClient.getDifficulty()
    assert isinstance(getDifficulty, float)

    getGenerate = rpcClient.getGenerate()
    assert isinstance(getGenerate, bool)

    getHashesPerSec = rpcClient.getHashesPerSec()
    assert isinstance(getHashesPerSec, int)

    getInfo = rpcClient.getInfo()
    assert isinstance(getInfo, rpc.InfoChainResult)

    getMempoolInfo = rpcClient.getMempoolInfo()
    assert isinstance(getMempoolInfo, rpc.GetMempoolInfoResult)

    getMiningInfo = rpcClient.getMiningInfo()
    assert isinstance(getMiningInfo, rpc.GetMiningInfoResult)

    getNetTotals = rpcClient.getNetTotals()
    assert isinstance(getNetTotals, rpc.GetNetTotalsResult)

    getNetworkHashPS = rpcClient.getNetworkHashPS()
    assert isinstance(getNetworkHashPS, int)

    getNetworkInfo = rpcClient.getNetworkInfo()
    assert isinstance(getNetworkInfo, rpc.GetNetworkInfoResult)

    getPeerInfo = rpcClient.getPeerInfo()
    assert isinstance(getPeerInfo[0], rpc.GetPeerInfoResult)

    getRawMempool = rpcClient.getRawMempool()
    assert isinstance(getRawMempool, list)
    mempoolTx = getRawMempool[0]

    existsMempoolTxs = rpcClient.existsMempoolTxs(getRawMempool[:3] +
                                                  [aTicket])
    assert existsMempoolTxs == [True, True, True, False]

    getRawMempool = rpcClient.getRawMempool(True)
    assert isinstance(getRawMempool[reversed(mempoolTx).hex()],
                      rpc.GetRawMempoolVerboseResult)

    getHeaders = rpcClient.getHeaders([blkHash414000], blkHash414005)
    assert blkHeader414002 in [header.serialize() for header in getHeaders]

    # This test will fail if --addrindex is not enabled in dcrd.
    getRawTransaction = rpcClient.getRawTransaction(aTicket)
    assert isinstance(getRawTransaction, MsgTx)

    decodeRawTransaction = rpcClient.decodeRawTransaction(getRawTransaction)
    assert isinstance(decodeRawTransaction, rpc.RawTransactionResult)

    rawaddr = txscript.extractStakeScriptHash(
        getRawTransaction.txOut[0].pkScript, opcode.OP_SSTX)
    if rawaddr:
        addressWithTickets = addrlib.AddressScriptHash(rawaddr,
                                                       mainnet).string()
    else:
        rawaddr = txscript.extractStakePubKeyHash(
            getRawTransaction.txOut[0].pkScript, opcode.OP_SSTX)
        addressWithTickets = addrlib.AddressPubKeyHash(rawaddr,
                                                       mainnet).string()

    getRawTransaction = rpcClient.getRawTransaction(aTicket, 1)
    assert isinstance(getRawTransaction, rpc.RawTransactionResult)

    getStakeDifficulty = rpcClient.getStakeDifficulty()
    assert isinstance(getStakeDifficulty, rpc.GetStakeDifficultyResult)

    getStakeVersionInfo = rpcClient.getStakeVersionInfo()
    assert isinstance(getStakeVersionInfo, rpc.GetStakeVersionInfoResult)

    getStakeVersions = rpcClient.getStakeVersions(blkHash414000, 3)
    assert isinstance(getStakeVersions[0], rpc.GetStakeVersionsResult)

    getTicketPoolValue = rpcClient.getTicketPoolValue()
    assert isinstance(getTicketPoolValue, float)

    getVoteInfo = rpcClient.getVoteInfo(7)
    assert isinstance(getVoteInfo, rpc.GetVoteInfoResult)

    # getWork will fail if --mininaddr is not set when starting dcrd
    with pytest.raises(DecredError):
        rpcClient.getWork()
    # getWork = rpcClient.getWork()
    # assert isinstance(getWork, rpc.GetWorkResult)

    dcrdHelp = rpcClient.help()
    assert isinstance(dcrdHelp, str)

    dcrdHelp = rpcClient.help("getinfo")
    assert isinstance(dcrdHelp, str)

    missedTickets = rpcClient.missedTickets()
    assert isinstance(missedTickets, list)

    assert rpcClient.node("connect", "127.0.0.1", "temp") is None

    revocableTicket = rpcClient.getRawTransaction(missedTickets[0])

    # create a ticket revoking transaction using txscript
    revocation = txscript.makeRevocation(revocableTicket, 3000)
    createRawSSRTx = rpcClient.createRawSSRTx(revocableTicket, 3000)

    # ours is just missing the block index
    revocation.txIn[0].blockIndex = createRawSSRTx.txIn[0].blockIndex
    assert createRawSSRTx.txHex() == revocation.txHex()

    # Using the revocation as an unspent output
    amt = revocableTicket.txOut[0].value
    script = revocableTicket.txOut[0].pkScript

    utxo = account.UTXO(
        address="",
        txHash=revocableTicket.hash(),
        vout=0,
        ts=None,
        scriptPubKey=script,
        satoshis=1,
        maturity=0,
        tinfo=None,
    )
    utxo2 = account.UTXO(
        address="",
        txHash=revocableTicket.hash(),
        vout=0,
        ts=None,
        scriptPubKey=script,
        satoshis=amt,
        maturity=0,
        tinfo=None,
    )
    amount = {cookedAddress2: amt + 1}

    zeroed = ByteArray(b"", length=20)
    changeAddr = addrlib.AddressPubKeyHash(zeroed, mainnet,
                                           crypto.STEcdsaSecp256k1).string()
    # only the first argument for couts is a non-zero value
    cout = rpc.COut(
        addr=mainnetAddress,
        commitAmt=0,
        changeAddr=changeAddr,
        changeAmt=0,
    )

    op = OutPoint(txHash=revocableTicket.hash(), idx=0, tree=wire.TxTreeStake)
    inputPool = txscript.ExtendedOutPoint(
        op=op,
        amt=1,
        pkScript=script,
    )
    inputMain = txscript.ExtendedOutPoint(
        op=op,
        amt=amt,
        pkScript=script,
    )
    ticketAddr = addrlib.AddressScriptHash(
        ByteArray(b58decode(cookedAddress2)[2:-4]), mainnet)
    mainAddr = addrlib.AddressScriptHash(
        ByteArray(b58decode(mainnetAddress)[2:-4]), mainnet)

    # create a ticket purchasing transaction using txscript
    ticketPurchase = txscript.makeTicket(mainnet, inputPool, inputMain,
                                         ticketAddr, mainAddr, amt + 1,
                                         mainAddr, 0)
    createRawSSTx = rpcClient.createRawSSTx([utxo, utxo2], amount,
                                            [cout, cout])

    # ours is just missing the block index
    ticketPurchase.txIn[0].blockIndex = createRawSSTx.txIn[0].blockIndex
    ticketPurchase.txIn[1].blockIndex = createRawSSTx.txIn[1].blockIndex
    assert createRawSSTx.txHex() == ticketPurchase.txHex()

    amount = {mainnetAddress: amt}
    txIn = TxIn(previousOutPoint=op, valueIn=amt)
    txOut = TxOut(
        value=amt,
        version=0,
        pkScript=txscript.payToAddrScript(mainAddr),
    )
    rawTx = MsgTx(
        serType=wire.TxSerializeFull,
        version=1,
        txIn=[txIn],
        txOut=[txOut],
        lockTime=0,
        expiry=0,
        cachedHash=None,
    )

    createRawTransaction = rpcClient.createRawTransaction([utxo2], amount)

    rawTx.txIn[0].blockIndex = createRawTransaction.txIn[0].blockIndex
    assert createRawTransaction.txHex() == rawTx.txHex()

    getTxOut = rpcClient.getTxOut(missedTickets[0], 0)
    assert isinstance(getTxOut, rpc.GetTxOutResult)

    existsLiveTicket = rpcClient.existsLiveTicket(liveTickets[0])
    assert existsLiveTicket

    existsLiveTicket = rpcClient.existsLiveTicket(missedTickets[0])
    assert not existsLiveTicket

    existsLiveTickets = rpcClient.existsLiveTickets(liveTickets[:5] +
                                                    missedTickets[:1] +
                                                    liveTickets[:2])
    assert existsLiveTickets == [
        True, True, True, True, True, False, True, True
    ]

    existsMissedTickets = rpcClient.existsMissedTickets(missedTickets[:8])
    assert existsMissedTickets == [True for _ in range(8)]

    with pytest.raises(DecredError):
        rpcClient.generate(2)

    rpcClient.ping()

    searchRawTransactions = rpcClient.searchRawTransactions(mainnetAddress)
    assert isinstance(searchRawTransactions[0], rpc.RawTransactionResult)

    searchRawTransactions = rpcClient.searchRawTransactions(
        mainnetAddress, False)
    msgtx = searchRawTransactions[0]
    assert isinstance(msgtx, MsgTx)

    with pytest.raises(DecredError):
        rpcClient.sendRawTransaction(msgtx)

    assert rpcClient.setGenerate(False) is None

    with pytest.raises(DecredError):
        rpcClient.submitBlock(ByteArray(b""))

    ticketFeeInfo = rpcClient.ticketFeeInfo()
    assert isinstance(ticketFeeInfo, rpc.TicketFeeInfoResult)

    ticketFeeInfo = rpcClient.ticketFeeInfo(5, 5)
    assert isinstance(ticketFeeInfo, rpc.TicketFeeInfoResult)

    ticketsForAddress = rpcClient.ticketsForAddress(addressWithTickets)
    assert aTicket in ticketsForAddress

    ticketVWAP = rpcClient.ticketVWAP()
    assert isinstance(ticketVWAP, float)

    ticketVWAP = rpcClient.ticketVWAP(414500)
    assert isinstance(ticketVWAP, float)

    ticketVWAP = rpcClient.ticketVWAP(414500, 414510)
    assert isinstance(ticketVWAP, float)

    txFeeInfo = rpcClient.txFeeInfo()
    assert isinstance(txFeeInfo, rpc.TxFeeInfoResult)

    txFeeInfo = rpcClient.txFeeInfo(5)
    assert isinstance(txFeeInfo, rpc.TxFeeInfoResult)
    tip = txFeeInfo.feeInfoBlocks[0].height

    txFeeInfo = rpcClient.txFeeInfo(5, tip - 5, tip)
    assert isinstance(txFeeInfo, rpc.TxFeeInfoResult)

    validateAddress = rpcClient.validateAddress(mainnetAddress)
    assert isinstance(validateAddress, rpc.ValidateAddressChainResult)
    assert validateAddress.isValid

    # Address for wrong network.
    validateAddress = rpcClient.validateAddress(testnetAddress)
    assert isinstance(validateAddress, rpc.ValidateAddressChainResult)
    assert not validateAddress.isValid

    # Address is bogus.
    validateAddress = rpcClient.validateAddress(nonsense)
    assert isinstance(validateAddress, rpc.ValidateAddressChainResult)
    assert not validateAddress.isValid

    verifyChain = rpcClient.verifyChain()
    assert verifyChain

    verifyMessage = rpcClient.verifyMessage(ownedAddress, signedMessage,
                                            message)
    assert verifyMessage

    # Signature is bogus.
    verifyMessage = rpcClient.verifyMessage(
        ownedAddress,
        nonsense,
        message,
    )
    assert not verifyMessage

    version = rpcClient.version()
    assert isinstance(version["dcrd"], rpc.VersionResult)
    assert isinstance(version["dcrdjsonrpcapi"], rpc.VersionResult)
Esempio n. 4
0
    def test_purchase_ticket(self):
        blockchain = dcrdata.DcrdataBlockchain(":memory:", testnet,
                                               "https://testnet.dcrdata.org")
        try:
            blockchain.connect()

            def broadcast(txHex):
                print("test skipping broadcast of transaction: %s" % txHex)
                return True

            blockchain.broadcast = broadcast
            txs = {}

            def getTx(txid):
                return txs[txid]

            blockchain.tx = getTx
            addrs = []
            keys = {}

            def internal():
                privKey = Curve.generateKey()
                pkHash = crypto.hash160(privKey.pub.serializeCompressed().b)
                addr = addrlib.AddressPubKeyHash(pkHash, testnet)
                addrs.append(addr)
                keys[addr.string()] = privKey
                return addr.string()

            def priv(addr):
                return keys[addr]

            class KeySource:
                def priv(self, *a):
                    return priv(*a)

                def internal(self):
                    return internal()

            def utxosource(amt, filter):
                nextVal = 10
                total = 0
                utxos = []

                while total < amt:
                    atoms = int(nextVal * 1e8)
                    privKey = Curve.generateKey()
                    pkHash = crypto.hash160(
                        privKey.pub.serializeCompressed().b)
                    addr = addrlib.AddressPubKeyHash(pkHash, testnet)
                    addrs.append(addr)
                    addrString = addr.string()
                    keys[addrString] = privKey
                    pkScript = txscript.makePayToAddrScript(
                        addrString, testnet)
                    txHash = rando.newHash()
                    txid = reversed(txHash).hex()
                    utxos.append(
                        account.UTXO(
                            address=addrString,
                            txHash=txHash,
                            vout=0,
                            ts=int(time.time()),
                            scriptPubKey=pkScript,
                            satoshis=atoms,
                        ))
                    tx = msgtx.MsgTx.new()
                    tx.addTxOut(msgtx.TxOut(value=atoms, pkScript=pkScript))
                    txs[txid] = tx
                    total += atoms
                    nextVal *= 2
                return utxos, True

            poolPriv = Curve.generateKey()
            pkHash = crypto.hash160(poolPriv.pub.serializeCompressed().b)
            poolAddr = addrlib.AddressPubKeyHash(pkHash, testnet)
            scriptHash = crypto.hash160("some script. doesn't matter".encode())
            scriptAddr = addrlib.AddressScriptHash(scriptHash, testnet)
            ticketPrice = blockchain.stakeDiff()

            request = account.TicketRequest(
                minConf=0,
                expiry=0,
                spendLimit=ticketPrice * 2 * 1.1,
                poolAddress=poolAddr.string(),
                votingAddress=scriptAddr.string(),
                ticketFee=0,
                poolFees=7.5,
                count=2,
                txFee=0,
            )

            ticket, spent, newUTXOs = blockchain.purchaseTickets(
                KeySource(), utxosource, request)
        finally:
            blockchain.close()