示例#1
0
    def test_auxpow(self, nodes):
        """
        Test behaviour of getauxpow.  Calling getauxpow should reserve
        a key from the pool, but it should be released again if the
        created block is not actually used.  On the other hand, if the
        auxpow is submitted and turned into a block, the keypool should
        be drained.
        """

        extraKeys = 0
        if self.options.descriptors:
            extraKeys = 12

        nodes[0].walletpassphrase('test', 12000)
        nodes[0].keypoolrefill(1)
        nodes[0].walletlock()
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1 + extraKeys)

        nodes[0].getauxblock()
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], extraKeys)
        nodes[0].generate(1)
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], extraKeys)
        auxblock = nodes[0].getauxblock()
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], extraKeys)

        target = reverseHex(auxblock['_target'])
        solved = computeAuxpow(auxblock['hash'], target, True)
        res = nodes[0].getauxblock(auxblock['hash'], solved)
        assert res
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], extraKeys)

        assert_raises_rpc_error(-12, 'Keypool ran out', nodes[0].getauxblock)
示例#2
0
def test_auxpow(nodes):
    """
    Test behaviour of getauxpow.  Calling getauxpow should reserve
    a key from the pool, but it should be released again if the
    created block is not actually used.  On the other hand, if the
    auxpow is submitted and turned into a block, the keypool should
    be drained.
    """

    nodes[0].walletpassphrase('test', 12000)
    nodes[0].keypoolrefill(1)
    nodes[0].walletlock()
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 2)

    nodes[0].getauxblock()
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 2)
    nodes[0].generate(1)
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)
    auxblock = nodes[0].getauxblock()
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)

    target = auxpow.reverseHex(auxblock['_target'])
    solved = auxpow.computeAuxpow(auxblock['hash'], target, True)
    res = nodes[0].getauxblock(auxblock['hash'], solved)
    assert res
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 0)

    try:
        nodes[0].getauxblock()
        raise AssertionError('Keypool should be exhausted by getauxblock')
    except JSONRPCException as e:
        assert (e.error['code'] == -12)
示例#3
0
def test_auxpow(nodes):
    """
    Test behaviour of getauxpow.  Calling getauxpow should reserve
    a key from the pool, but it should be released again if the
    created block is not actually used.  On the other hand, if the
    auxpow is submitted and turned into a block, the keypool should
    be drained.
    """

    nodes[0].walletpassphrase('test', 12000)
    nodes[0].keypoolrefill(1)
    nodes[0].walletlock()
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 1)

    nodes[0].getauxblock()
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 1)
    nodes[0].generate(1)
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 1)
    auxblock = nodes[0].getauxblock()
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 1)

    target = reverseHex(auxblock['_target'])
    solved = computeAuxpow(auxblock['hash'], target, True)
    res = nodes[0].getauxblock(auxblock['hash'], solved)
    assert res
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 0)

    assert_raises_rpc_error(-12, 'Keypool ran out', nodes[0].getauxblock)
示例#4
0
def test_auxpow(nodes):
    """
    Test behaviour of getauxpow.  Calling getauxpow should reserve
    a key from the pool, but it should be released again if the
    created block is not actually used.  On the other hand, if the
    auxpow is submitted and turned into a block, the keypool should
    be drained.
    """

    nodes[0].walletpassphrase('test', 12000)
    nodes[0].keypoolrefill(1)
    nodes[0].walletlock()
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 2)

    nodes[0].getauxblock()
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 2)
    nodes[0].generate(1)
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 1)
    auxblock = nodes[0].getauxblock()
    assert_equal (nodes[0].getwalletinfo()['keypoolsize'], 1)

    target = auxpow.reverseHex(auxblock['_target'])
    solved = auxpow.computeAuxpow(auxblock['hash'], target, True)
    res = nodes[0].getauxblock(auxblock['hash'], solved)
    assert res
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 0)

    try:
        nodes[0].getauxblock()
        raise AssertionError('Keypool should be exhausted by getauxblock')
    except JSONRPCException as e:
        assert(e.error['code']==-12)
示例#5
0
def test_auxpow(nodes):
    """
    Test behaviour of getauxpow.  Calling getauxpow should reserve
    a key from the pool, but it should be released again if the
    created block is not actually used.  On the other hand, if the
    auxpow is submitted and turned into a block, the keypool should
    be drained.
    """

    nodes[0].walletpassphrase('test', 12000)
    nodes[0].keypoolrefill(2)
    nodes[0].walletlock()
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 2)

    nodes[0].getauxblock()
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 2)
    nodes[0].generate(1)
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)
    auxblock = nodes[0].getauxblock()
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)

    target = auxpow.reverseHex(auxblock['_target'])
    solved = auxpow.computeAuxpow(auxblock['hash'], target, True)
    res = nodes[0].getauxblock(auxblock['hash'], solved)
    assert res
    assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 0)

    assert_raises_jsonrpc(-12, 'Keypool ran out', nodes[0].getauxblock)
示例#6
0
def mineAuxpowBlockWithMethods (create, submit):
  """
  Mine an auxpow block, using the given methods for creation and submission.
  """

  auxblock = create ()
  target = auxpow.reverseHex (auxblock['_target'])
  apow = computeAuxpow (auxblock['hash'], target, True)
  res = submit (auxblock['hash'], apow)
  assert res

  return auxblock['hash']
示例#7
0
def mineWorkBlockWithMethods (rpc, create, submit):
  """
  Mine a stand-alone block, using the given methods for creation and submission.
  """

  work = create ()
  target = auxpow.reverseHex (work['target'])
  solved = solveData (work['data'], target, True)
  res = submit (work['hash'], solved)
  assert res

  return work['hash']
示例#8
0
def mineAuxpowBlockWithMethods(create, submit):
    """
  Mine an auxpow block, using the given methods for creation and submission.
  """

    auxblock = create()
    target = auxpow.reverseHex(auxblock['_target'])
    apow = computeAuxpow(auxblock['hash'], target, True)
    res = submit(auxblock['hash'], apow)
    assert res

    return auxblock['hash']
示例#9
0
    def addAuxpow(self, block, blkHash, ok):
        """
    Fills in the auxpow for the given block message.  It is either
    chosen to be valid (ok = True) or invalid (ok = False).
    """

        tmpl = self.nodes[0].getauxblock()
        target = reverseHex(tmpl["_target"])

        auxpowHex = computeAuxpow(blkHash, target, ok)
        block.auxpow = CAuxPow()
        block.auxpow.deserialize(BytesIO(hex_str_to_bytes(auxpowHex)))

        return block
示例#10
0
    def run_test(self):
        # Check for difficulty reports in various RPC calls.  Where the "current"
        # state is involved, we get two (for each algo).  Where a particular block
        # is involved, we just get that block's difficulty (whatever the algo).
        dual = []
        dual.append(self.nodes[0].getblockchaininfo())
        dual.append(self.nodes[0].getmininginfo())
        for data in dual:
            assert 'difficulty_sha256d' in data
            assert 'difficulty_scrypt' in data
            assert 'difficulty' not in data
        bestHash = self.nodes[0].getbestblockhash()
        data = self.nodes[0].getblock(bestHash)
        assert 'difficulty' in data
        assert 'difficulty_sha256d' not in data
        assert 'difficulty_scrypt' not in data

        # Check getdifficulty RPC call.
        diffSHA = self.nodes[0].getdifficulty(0)
        assert_equal(diffSHA, dual[0]['difficulty_sha256d'])
        diffScrypt = self.nodes[0].getdifficulty(1)
        assert_equal(diffScrypt, dual[0]['difficulty_scrypt'])
        assert_raises_jsonrpc(-1, None, self.nodes[0].getdifficulty)

        # Generate a few blocks with SHA256D.  Ensure that they are, indeed,
        # with the correct algo.
        arr1 = self.nodes[0].generate(5)
        arr2 = self.nodes[0].generate(5, 0)
        for blk in arr1 + arr2:
            data = self.nodes[0].getblock(blk)
            assert_equal(data['algo'], 0)

        # Generate a few blocks with scrypt.  Ensure the algo parameter.
        # Furthermore, at least one of them "should" have an obviously high
        # hash value.  It may, of course, happen that this is not the case,
        # but the probability for that is negligible (about 2^(-20)).
        arr = self.nodes[0].generate(20, 1)
        foundHigh = False
        for blk in arr:
            data = self.nodes[0].getblock(blk)
            assert_equal(data['algo'], 1)
            if blk[0] in '89abcdef':
                foundHigh = True
        assert foundHigh

        # Verify check for algo parameter.
        for p in [-1, 2]:
            assert_raises_jsonrpc(-8, 'invalid algo', self.nodes[0].generate,
                                  1, p)

        # Briefly test generatetoaddress as well.
        for algo in [0, 1]:
            addr = self.nodes[0].getnewaddress()
            blkhash = self.nodes[0].generatetoaddress(1, addr, algo)
            assert_equal(1, len(blkhash))
            data = self.nodes[0].getblock(blkhash[0])
            assert_equal(algo, data['algo'])
            coinbaseTx = data['tx'][0]
            utxo = self.nodes[0].gettxout(coinbaseTx, 0)
            assert_equal([addr], utxo['scriptPubKey']['addresses'])

        # Check updates of the returned block (or not) with aux mining.
        # Note that this behaviour needs not necessarily be exactly as tested,
        # but the test ensures that no change is introduced accidentally.
        coinbaseAddr = self.nodes[0].getnewaddress()
        auxblock1 = self.nodes[0].createauxblock(coinbaseAddr)
        auxblock2 = self.nodes[0].createauxblock(coinbaseAddr, 0)
        assert_equal(auxblock1['hash'], auxblock2['hash'])
        auxblock2 = self.nodes[0].createauxblock(coinbaseAddr, 1)
        auxblock3 = self.nodes[0].createauxblock(coinbaseAddr, 1)
        assert_equal(auxblock2['hash'], auxblock3['hash'])
        assert auxblock2['hash'] != auxblock1['hash']
        auxblock3 = self.nodes[0].createauxblock(coinbaseAddr)
        assert auxblock1['hash'] != auxblock3['hash']

        # Use createauxblock with explicit algo to mine a SHA256D block.
        # Assert that this works (the block is saved) even if we request
        # another scrypt block before.
        auxblock = self.nodes[0].createauxblock(coinbaseAddr)
        assert_equal(auxblock['chainid'], 6)
        assert_equal(auxblock['algo'], 0)
        dummy = self.nodes[0].createauxblock(coinbaseAddr, 1)
        assert_equal(dummy['chainid'], 2)
        assert_equal(dummy['algo'], 1)

        # Solve the auxpow requested before.
        curcnt = self.nodes[0].getblockcount()
        target = auxpow.reverseHex(auxblock['_target'])
        apow = auxpow.computeAuxpow(auxblock['hash'], target, True)
        res = self.nodes[0].submitauxblock(auxblock['hash'], apow)
        assert res

        # Check submitted data.
        assert_equal(self.nodes[0].getblockcount(), curcnt + 1)
        data = self.nodes[0].getblock(auxblock['hash'])
        assert_equal(data['algo'], 0)

        # Mine an scrypt auxpow.  Since there is no built-in Python
        # function to scrypt, we do it differently:  Simply try submitting
        # until the block is accepted.  Since we need on average 2 trials,
        # this is no big hit.
        trials = 0
        curcnt = self.nodes[0].getblockcount()
        ok = False
        while not ok:
            if trials > 100:
                raise AssertionError("failed to merge-mine scrypt auxpow")
            trials += 1

            # Force an update of the block so we get a new trial.
            self.nodes[0].createauxblock(coinbaseAddr, 0)
            auxblock = self.nodes[0].createauxblock(coinbaseAddr, 1)

            target = auxpow.reverseHex(auxblock['_target'])
            apow = auxpow.computeAuxpow(auxblock['hash'], target, False)
            ok = self.nodes[0].submitauxblock(auxblock['hash'], apow)
        print("Found scrypt block after %d trials." % trials)

        # Check submitted auxblock.
        assert_equal(self.nodes[0].getblockcount(), curcnt + 1)
        data = self.nodes[0].getblock(auxblock['hash'])
        assert_equal(data['algo'], 1)
示例#11
0
    def run_test(self):
        BitcoinTestFramework.run_test(self)

        # Generate a block so that we are not "downloading blocks".
        self.nodes[0].generate(1)

        # Compare basic data of getauxblock to getblocktemplate.
        auxblock = self.nodes[0].getauxblock()
        blocktemplate = self.nodes[0].getblocktemplate()
        assert_equal(auxblock['coinbasevalue'], blocktemplate['coinbasevalue'])
        assert_equal(auxblock['bits'], blocktemplate['bits'])
        assert_equal(auxblock['height'], blocktemplate['height'])
        assert_equal(auxblock['previousblockhash'],
                     blocktemplate['previousblockhash'])

        # Compare target and take byte order into account.
        target = auxblock['_target']
        reversedTarget = auxpow.reverseHex(target)
        assert_equal(reversedTarget, blocktemplate['target'])

        # Verify data that can be found in another way.
        assert_equal(auxblock['chainid'], 1)
        assert_equal(auxblock['height'], self.nodes[0].getblockcount() + 1)
        assert_equal(auxblock['previousblockhash'],
                     self.nodes[0].getblockhash(auxblock['height'] - 1))

        # Calling again should give the same block.
        auxblock2 = self.nodes[0].getauxblock()
        assert_equal(auxblock2, auxblock)

        # If we receive a new block, the old hash will be replaced.
        self.sync_all()
        self.nodes[1].generate(1)
        self.sync_all()
        auxblock2 = self.nodes[0].getauxblock()
        assert auxblock['hash'] != auxblock2['hash']
        try:
            self.nodes[0].getauxblock(auxblock['hash'], "x")
            raise AssertionError("invalid block hash accepted")
        except JSONRPCException as exc:
            assert_equal(exc.error['code'], -8)

        # Invalid format for auxpow.
        try:
            self.nodes[0].getauxblock(auxblock2['hash'], "x")
            raise AssertionError("malformed auxpow accepted")
        except JSONRPCException as exc:
            assert_equal(exc.error['code'], -1)

        # Invalidate the block again, send a transaction and query for the
        # auxblock to solve that contains the transaction.
        self.nodes[0].generate(1)
        addr = self.nodes[1].getnewaddress()
        txid = self.nodes[0].sendtoaddress(addr, 1)
        self.sync_all()
        assert_equal(self.nodes[1].getrawmempool(), [txid])
        auxblock = self.nodes[0].getauxblock()
        blocktemplate = self.nodes[0].getblocktemplate()
        target = blocktemplate['target']

        # Compute invalid auxpow.
        apow = auxpow.computeAuxpow(auxblock['hash'], target, False)
        res = self.nodes[0].getauxblock(auxblock['hash'], apow)
        assert not res

        # Compute and submit valid auxpow.
        apow = auxpow.computeAuxpow(auxblock['hash'], target, True)
        res = self.nodes[0].getauxblock(auxblock['hash'], apow)
        assert res

        # Make sure that the block is indeed accepted.
        self.sync_all()
        assert_equal(self.nodes[1].getrawmempool(), [])
        height = self.nodes[1].getblockcount()
        assert_equal(height, auxblock['height'])
        assert_equal(self.nodes[1].getblockhash(height), auxblock['hash'])

        # Call getblock and verify the auxpow field.
        data = self.nodes[1].getblock(auxblock['hash'])
        assert 'auxpow' in data
        auxJson = data['auxpow']
        assert_equal(auxJson['index'], 0)
        assert_equal(auxJson['parentblock'], apow[-160:])

        # Check that previous blocks don't have 'auxpow' in their getblock JSON.
        oldHash = self.nodes[1].getblockhash(100)
        data = self.nodes[1].getblock(oldHash)
        assert 'auxpow' not in data

        # Check that it paid correctly to the first node.
        t = self.nodes[0].listtransactions("", 1)
        assert_equal(len(t), 1)
        t = t[0]
        assert_equal(t['category'], "immature")
        assert_equal(t['blockhash'], auxblock['hash'])
        assert t['generated']
        assert t['amount'] >= Decimal("25")
        assert_equal(t['confirmations'], 1)

        # Verify the coinbase script.  Ensure that it includes the block height
        # to make the coinbase tx unique.  The expected block height is around
        # 200, so that the serialisation of the CScriptNum ends in an extra 00.
        # The vector has length 2, which makes up for 02XX00 as the serialised
        # height.  Check this.
        blk = self.nodes[1].getblock(auxblock['hash'])
        tx = self.nodes[1].getrawtransaction(blk['tx'][0], 1)
        coinbase = tx['vin'][0]['coinbase']
        assert_equal("02%02x00" % auxblock['height'], coinbase[0:6])
示例#12
0
    def test_auxpow(nodes):
        """
        Test behaviour of getauxpow.  Calling getauxpow should reserve
        a key from the pool, but it should be released again if the
        created block is not actually used.  On the other hand, if the
        auxpow is submitted and turned into a block, the keypool should
        be drained.
        """

        nodes[0].walletpassphrase('test', 12000)
        nodes[0].keypoolrefill(1)
        nodes[0].walletlock()
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)

        nodes[0].getauxblock()
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)
        nodes[0].generate(1)
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)
        auxblock = nodes[0].getauxblock()
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 1)

        target = reverseHex(auxblock['_target'])
        solved = computeAuxpow(auxblock['hash'], target, True)
        res = nodes[0].getauxblock(auxblock['hash'], solved)
        assert res
        assert_equal(nodes[0].getwalletinfo()['keypoolsize'], 0)

        assert_raises_rpc_error(-12, 'Keypool ran out', nodes[0].getauxblock)

        # drain the internal keys
        nodes[0].getrawchangeaddress()
        nodes[0].getrawchangeaddress()
        nodes[0].getrawchangeaddress()
        nodes[0].getrawchangeaddress()
        nodes[0].getrawchangeaddress()
        nodes[0].getrawchangeaddress()
        addr = set()
        # the next one should fail
        assert_raises_rpc_error(-12, "Keypool ran out",
                                nodes[0].getrawchangeaddress)

        # drain the external keys
        addr.add(nodes[0].getnewaddress())
        addr.add(nodes[0].getnewaddress())
        addr.add(nodes[0].getnewaddress())
        addr.add(nodes[0].getnewaddress())
        addr.add(nodes[0].getnewaddress())
        addr.add(nodes[0].getnewaddress())
        assert len(addr) == 6
        # the next one should fail
        assert_raises_rpc_error(
            -12, "Error: Keypool ran out, please call keypoolrefill first",
            nodes[0].getnewaddress)

        # refill keypool with three new addresses
        nodes[0].walletpassphrase('test', 1)
        nodes[0].keypoolrefill(3)

        # test walletpassphrase timeout
        time.sleep(1.1)
        assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0)

        # drain the keypool
        for _ in range(3):
            nodes[0].getnewaddress()
        assert_raises_rpc_error(-12, "Keypool ran out", nodes[0].getnewaddress)

        nodes[0].walletpassphrase('test', 100)
        nodes[0].keypoolrefill(100)
        wi = nodes[0].getwalletinfo()
        assert_equal(wi['keypoolsize_hd_internal'], 100)
        assert_equal(wi['keypoolsize'], 100)
示例#13
0
  def run_test (self):
    BitcoinTestFramework.run_test (self)

    # Generate a block so that we are not "downloading blocks".
    self.nodes[0].generate (1)

    # We used to compare to getblocktemplate, but this call is gone
    # now completely for merge-mining.

    # Verify data that can be found in another way.
    auxblock = self.nodes[0].getauxblock ()
    assert_equal (auxblock['chainid'], 1)
    assert_equal (auxblock['height'], self.nodes[0].getblockcount () + 1)
    assert_equal (auxblock['previousblockhash'], self.nodes[0].getblockhash (auxblock['height'] - 1))

    # Calling again should give the same block.
    auxblock2 = self.nodes[0].getauxblock ()
    assert_equal (auxblock2, auxblock)

    # If we receive a new block, the old hash will be replaced.
    self.sync_all ()
    self.nodes[1].generate (1)
    self.sync_all ()
    auxblock2 = self.nodes[0].getauxblock ()
    assert auxblock['hash'] != auxblock2['hash']
    try:
      self.nodes[0].getauxblock (auxblock['hash'], "x")
      raise AssertionError ("invalid block hash accepted")
    except JSONRPCException as exc:
      assert_equal (exc.error['code'], -8)

    # Invalid format for auxpow.
    try:
      self.nodes[0].getauxblock (auxblock2['hash'], "x")
      raise AssertionError ("malformed auxpow accepted")
    except JSONRPCException as exc:
      assert_equal (exc.error['code'], -1)

    # Invalidate the block again, send a transaction and query for the
    # auxblock to solve that contains the transaction.
    self.nodes[0].generate (1)
    addr = self.nodes[1].getnewaddress ()
    txid = self.nodes[0].sendtoaddress (addr, 1)
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [txid])
    auxblock = self.nodes[0].getauxblock ()
    target = auxpow.reverseHex (auxblock['_target'])

    # Compute invalid auxpow.
    apow = auxpow.computeAuxpow (auxblock['hash'], target, False)
    res = self.nodes[0].getauxblock (auxblock['hash'], apow)
    assert not res

    # Compute and submit valid auxpow.
    apow = auxpow.computeAuxpow (auxblock['hash'], target, True)
    res = self.nodes[0].getauxblock (auxblock['hash'], apow)
    assert res

    # Make sure that the block is indeed accepted.
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [])
    height = self.nodes[1].getblockcount ()
    assert_equal (height, auxblock['height'])
    assert_equal (self.nodes[1].getblockhash (height), auxblock['hash'])

    # Call getblock and verify the auxpow field.
    data = self.nodes[1].getblock (auxblock['hash'])
    assert 'auxpow' in data
    auxJson = data['auxpow']
    assert_equal (auxJson['index'], 0)
    assert_equal (auxJson['chainindex'], 0)
    assert_equal (auxJson['merklebranch'], [])
    assert_equal (auxJson['chainmerklebranch'], [])
    assert_equal (auxJson['parentblock'], apow[-160:])

    # Also previous blocks should have 'auxpow', since all blocks (also
    # those generated by "generate") are merge-mined.
    oldHash = self.nodes[1].getblockhash (100)
    data = self.nodes[1].getblock (oldHash)
    assert 'auxpow' in data

    # Check that it paid correctly to the first node.
    t = self.nodes[0].listtransactions ("", 1)
    assert_equal (len (t), 1)
    t = t[0]
    assert_equal (t['category'], "immature")
    assert_equal (t['blockhash'], auxblock['hash'])
    assert t['generated']
    assert t['amount'] >= Decimal ("25")
    assert_equal (t['confirmations'], 1)

    # Verify the coinbase script.  Ensure that it includes the block height
    # to make the coinbase tx unique.  The expected block height is around
    # 200, so that the serialisation of the CScriptNum ends in an extra 00.
    # The vector has length 2, which makes up for 02XX00 as the serialised
    # height.  Check this.
    blk = self.nodes[1].getblock (auxblock['hash'])
    tx = self.nodes[1].getrawtransaction (blk['tx'][0], 1)
    coinbase = tx['vin'][0]['coinbase']
    assert_equal ("02%02x00" % auxblock['height'], coinbase[0 : 6])

    # Ensure that the payout address is changed from one block to the next.
    addr1 = self.getCoinbaseAddr (auxblock['hash'])
    newHash = auxpow.mineAuxpowBlock (self.nodes[0])
    self.sync_all ()
    addr2 = self.getCoinbaseAddr (newHash)
    assert addr1 != addr2
    valid = self.nodes[0].validateaddress (addr1)
    assert valid['ismine']
    valid = self.nodes[0].validateaddress (addr2)
    assert valid['ismine']
示例#14
0
    def test_common(self, create, submit):
        """
    Common test code that is shared between the tests for getwork and the
    creatework / submitwork method pair.
    """

        # Verify data that can be found in another way.
        work = create()
        assert_equal(work['algo'], 'neoscrypt')
        assert_equal(work['height'], self.nodes[0].getblockcount() + 1)
        assert_equal(work['previousblockhash'],
                     self.nodes[0].getblockhash(work['height'] - 1))

        # Invalid format for data.
        assert_raises_rpc_error(-8, None, submit, "", "x")
        assert_raises_rpc_error(-8, None, submit, "", "00")

        # Compute invalid work.
        target = reverseHex(work['target'])
        solved = solveData(work['data'], target, False)
        res = submit(work['hash'], solved)
        assert not res

        # Compute and submit valid work.
        solved = solveData(work['data'], target, True)
        res = submit(work['hash'], solved)
        assert res

        # Make sure that the block is indeed accepted.
        height = self.nodes[0].getblockcount()
        assert_equal(height, work['height'])

        # Call getblock and verify the powdata field.
        data = self.nodes[0].getblock(work['hash'])
        assert 'powdata' in data
        data = data['powdata']
        assert_equal(data['algo'], 'neoscrypt')
        assert_equal(data['mergemined'], False)
        assert_equal(data['bits'], '207fffff')
        assert 'difficulty' in data
        fakeHeader = codecs.decode(solved, 'hex_codec')
        fakeHeader = getworkByteswap(fakeHeader)
        fakeHeader = codecs.encode(fakeHeader, 'hex_codec')
        fakeHeader = codecs.decode(fakeHeader, 'ascii')
        assert_equal(data['fakeheader'], fakeHeader)

        # Also previous blocks should have 'powdata', since all blocks (also
        # those generated by "generate") are mined with it.
        oldHash = self.nodes[0].getblockhash(100)
        data = self.nodes[0].getblock(oldHash)
        assert 'powdata' in data

        # Check that it paid correctly to the first node.
        t = self.nodes[0].listtransactions("*", 1)
        assert_equal(len(t), 1)
        t = t[0]
        assert_equal(t['category'], "immature")
        assert t['generated']
        assert_greater_than_or_equal(t['amount'], Decimal("1"))
        assert_equal(t['confirmations'], 1)

        # Mine a block using the hash-less form of submit.
        work = create()
        target = reverseHex(work['target'])
        solved = solveData(work['data'], target, True)
        res = submit(solved)
        assert res
        assert_equal(self.nodes[0].getbestblockhash(), work['hash'])
示例#15
0
  def test_common (self, create, submit):
    """
    Common test code that is shared between the tests for getauxblock and the
    createauxblock / submitauxblock method pair.
    """

    # Verify data that can be found in another way.
    auxblock = create ()
    assert_equal (auxblock['chainid'], 1)
    assert_equal (auxblock['height'], self.nodes[0].getblockcount () + 1)
    assert_equal (auxblock['previousblockhash'],
                  self.nodes[0].getblockhash (auxblock['height'] - 1))

    # Calling again should give the same block.
    auxblock2 = create ()
    assert_equal (auxblock2, auxblock)

    # If we receive a new block, the old hash will be replaced.
    self.sync_all ()
    self.nodes[1].generate (1)
    self.sync_all ()
    auxblock2 = create ()
    assert auxblock['hash'] != auxblock2['hash']
    assert_raises_rpc_error (-8, 'block hash unknown', submit,
                             auxblock['hash'], "x")

    # Invalid format for auxpow.
    assert_raises_rpc_error (-1, None, submit,
                             auxblock2['hash'], "x")

    # Invalidate the block again, send a transaction and query for the
    # auxblock to solve that contains the transaction.
    self.nodes[0].generate (1)
    addr = self.nodes[1].getnewaddress ()
    txid = self.nodes[0].sendtoaddress (addr, 1)
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [txid])
    auxblock = create ()
    target = reverseHex (auxblock['_target'])

    # Cross-check target value with GBT to make explicitly sure that it is
    # correct (not just implicitly by successfully mining blocks for it
    # later on).
    gbt = self.nodes[0].getblocktemplate ({"rules": ["segwit"]})
    assert_equal (target, gbt['target'].encode ("ascii"))

    # Compute invalid auxpow.
    apow = computeAuxpow (auxblock['hash'], target, False)
    res = submit (auxblock['hash'], apow)
    assert not res

    # Compute and submit valid auxpow.
    apow = computeAuxpow (auxblock['hash'], target, True)
    res = submit (auxblock['hash'], apow)
    assert res

    # Make sure that the block is indeed accepted.
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [])
    height = self.nodes[1].getblockcount ()
    assert_equal (height, auxblock['height'])
    assert_equal (self.nodes[1].getblockhash (height), auxblock['hash'])

    # Call getblock and verify the auxpow field.
    data = self.nodes[1].getblock (auxblock['hash'])
    assert 'auxpow' in data
    auxJson = data['auxpow']
    assert_equal (auxJson['chainindex'], 0)
    assert_equal (auxJson['merklebranch'], [])
    assert_equal (auxJson['chainmerklebranch'], [])
    assert_equal (auxJson['parentblock'], apow[-160:])

    # Also previous blocks should have 'auxpow', since all blocks (also
    # those generated by "generate") are merge-mined.
    oldHash = self.nodes[1].getblockhash (100)
    data = self.nodes[1].getblock (oldHash)
    assert 'auxpow' in data

    # Check that it paid correctly to the first node.
    t = self.nodes[0].listtransactions ("*", 1)
    assert_equal (len (t), 1)
    t = t[0]
    assert_equal (t['category'], "immature")
    assert_equal (t['blockhash'], auxblock['hash'])
    assert t['generated']
    assert_greater_than_or_equal (t['amount'], Decimal ("1"))
    assert_equal (t['confirmations'], 1)

    # Verify the coinbase script.  Ensure that it includes the block height
    # to make the coinbase tx unique.  The expected block height is around
    # 200, so that the serialisation of the CScriptNum ends in an extra 00.
    # The vector has length 2, which makes up for 02XX00 as the serialised
    # height.  Check this.  (With segwit, the height is different, so we skip
    # this for simplicity.)
    if not self.options.segwit:
      blk = self.nodes[1].getblock (auxblock['hash'])
      tx = self.nodes[1].getrawtransaction (blk['tx'][0], True, blk['hash'])
      coinbase = tx['vin'][0]['coinbase']
      assert_equal ("02%02x00" % auxblock['height'], coinbase[0 : 6])
示例#16
0
    def run_test(self):
        # Generate a block so that we are not "downloading blocks".
        self.nodes[0].generate(1)

        # specify coinbase output
        coinbaseAddress = self.nodes[0].getnewaddress()

        #
        # check params
        #
        # missing address
        assert_raises_jsonrpc(-1, None, self.nodes[0].createauxblock)
        # invalid address
        assert_raises_jsonrpc(-8, "Invalid coinbase payout address",
                              self.nodes[0].createauxblock,
                              "this_a_invalid_address")

        # Verify data that can be found in another way.
        auxblock = self.nodes[0].createauxblock(coinbaseAddress)
        assert_equal(auxblock['chainid'], 1)
        assert_equal(auxblock['height'], self.nodes[0].getblockcount() + 1)
        assert_equal(auxblock['previousblockhash'],
                     self.nodes[0].getblockhash(auxblock['height'] - 1))

        # Calling again should give the same block.
        auxblock2 = self.nodes[0].createauxblock(coinbaseAddress)
        assert_equal(auxblock2, auxblock)

        # If we receive a new block, the old hash will be replaced.
        self.sync_all()
        self.nodes[1].generate(1)
        self.sync_all()
        auxblock2 = self.nodes[0].createauxblock(coinbaseAddress)
        assert auxblock['hash'] != auxblock2['hash']

        # Invalid format for auxpow.
        assert_raises_jsonrpc(-8, 'block hash unknown',
                              self.nodes[0].submitauxblock, auxblock['hash'],
                              "x")
        assert_raises_jsonrpc(-1, None, self.nodes[0].submitauxblock,
                              auxblock2['hash'], "x")

        # Invalidate the block again, send a transaction and query for the
        # auxblock to solve that contains the transaction.
        self.nodes[0].generate(1)
        addr = self.nodes[1].getnewaddress()
        txid = self.nodes[0].sendtoaddress(addr, 1)
        self.sync_all()
        assert_equal(self.nodes[1].getrawmempool(), [txid])
        auxblock = self.nodes[0].createauxblock(coinbaseAddress)
        target = auxpow.reverseHex(auxblock['_target'])

        # Compute invalid auxpow.
        apow = auxpow.computeAuxpow(auxblock['hash'], target, False)
        res = self.nodes[0].submitauxblock(auxblock['hash'], apow)
        assert not res

        # Compute and submit valid auxpow.
        apow = auxpow.computeAuxpow(auxblock['hash'], target, True)
        res = self.nodes[0].submitauxblock(auxblock['hash'], apow)
        assert res

        # Make sure that the block is indeed accepted.
        self.sync_all()
        assert_equal(self.nodes[1].getrawmempool(), [])
        height = self.nodes[1].getblockcount()
        assert_equal(height, auxblock['height'])
        assert_equal(self.nodes[1].getblockhash(height), auxblock['hash'])

        # Call getblock and verify the auxpow field.
        data = self.nodes[1].getblock(auxblock['hash'])
        assert 'auxpow' in data
        auxJson = data['auxpow']
        assert_equal(auxJson['index'], 0)
        assert_equal(auxJson['chainindex'], 0)
        assert_equal(auxJson['merklebranch'], [])
        assert_equal(auxJson['chainmerklebranch'], [])
        assert_equal(auxJson['parentblock'], apow[-160:])

        # Also previous blocks should have 'auxpow', since all blocks (also
        # those generated by "generate") are merge-mined.
        oldHash = self.nodes[1].getblockhash(100)
        data = self.nodes[1].getblock(oldHash)
        assert 'auxpow' in data

        # Check that it paid correctly to the first node.
        t = self.nodes[0].listtransactions("", 1)
        assert_equal(len(t), 1)
        t = t[0]
        assert_equal(t['category'], "immature")
        assert_equal(t['blockhash'], auxblock['hash'])
        assert t['generated']
        assert t['amount'] >= Decimal("25")
        assert_equal(t['confirmations'], 1)

        # Verify the coinbase script.  Ensure that it includes the block height
        # to make the coinbase tx unique.  The expected block height is around
        # 200, so that the serialisation of the CScriptNum ends in an extra 00.
        # The vector has length 2, which makes up for 02XX00 as the serialised
        # height.  Check this.
        blk = self.nodes[1].getblock(auxblock['hash'])
        tx = self.nodes[1].getrawtransaction(blk['tx'][0], 1)
        coinbase = tx['vin'][0]['coinbase']
        assert_equal("02%02x00" % auxblock['height'], coinbase[0:6])

        # Ensure that the payout address is the one which we specify
        addr1 = auxpow.getCoinbaseAddr(self.nodes[1], auxblock['hash'])
        assert addr1 == coinbaseAddress
        newHash = auxpow.mineAuxpowBlock2(self.nodes[0], coinbaseAddress)
        self.sync_all()
        addr2 = auxpow.getCoinbaseAddr(self.nodes[1], newHash)
        assert addr2 == coinbaseAddress
示例#17
0
  def run_test (self):
    BitcoinTestFramework.run_test (self)

    # Generate a block so that we are not "downloading blocks".
    self.nodes[0].generate (1)

    # Compare basic data of getauxblock to getblocktemplate.
    auxblock = self.nodes[0].getauxblock ()
    blocktemplate = self.nodes[0].getblocktemplate ()
    assert_equal (auxblock['coinbasevalue'], blocktemplate['coinbasevalue'])
    assert_equal (auxblock['bits'], blocktemplate['bits'])
    assert_equal (auxblock['height'], blocktemplate['height'])
    assert_equal (auxblock['previousblockhash'], blocktemplate['previousblockhash'])

    # Compare target and take byte order into account.
    target = auxblock['_target']
    reversedTarget = auxpow.reverseHex (target)
    assert_equal (reversedTarget, blocktemplate['target'])

    # Verify data that can be found in another way.
    assert_equal (auxblock['chainid'], 1)
    assert_equal (auxblock['height'], self.nodes[0].getblockcount () + 1)
    assert_equal (auxblock['previousblockhash'], self.nodes[0].getblockhash (auxblock['height'] - 1))

    # Calling again should give the same block.
    auxblock2 = self.nodes[0].getauxblock ()
    assert_equal (auxblock2, auxblock)

    # If we receive a new block, the old hash will be replaced.
    self.sync_all ()
    self.nodes[1].generate (1)
    self.sync_all ()
    auxblock2 = self.nodes[0].getauxblock ()
    assert auxblock['hash'] != auxblock2['hash']
    try:
      self.nodes[0].getauxblock (auxblock['hash'], "x")
      raise AssertionError ("invalid block hash accepted")
    except JSONRPCException as exc:
      assert_equal (exc.error['code'], -8)

    # Invalid format for auxpow.
    try:
      self.nodes[0].getauxblock (auxblock2['hash'], "x")
      raise AssertionError ("malformed auxpow accepted")
    except JSONRPCException as exc:
      assert_equal (exc.error['code'], -1)

    # Invalidate the block again, send a transaction and query for the
    # auxblock to solve that contains the transaction.
    self.nodes[0].generate (1)
    addr = self.nodes[1].getnewaddress ()
    txid = self.nodes[0].sendtoaddress (addr, 1)
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [txid])
    auxblock = self.nodes[0].getauxblock ()
    blocktemplate = self.nodes[0].getblocktemplate ()
    target = blocktemplate['target']

    # Compute invalid auxpow.
    apow = auxpow.computeAuxpow (auxblock['hash'], target, False)
    res = self.nodes[0].getauxblock (auxblock['hash'], apow)
    assert not res

    # Compute and submit valid auxpow.
    apow = auxpow.computeAuxpow (auxblock['hash'], target, True)
    res = self.nodes[0].getauxblock (auxblock['hash'], apow)
    assert res

    # Make sure that the block is indeed accepted.
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [])
    height = self.nodes[1].getblockcount ()
    assert_equal (height, auxblock['height'])
    assert_equal (self.nodes[1].getblockhash (height), auxblock['hash'])

    # Call getblock and verify the auxpow field.
    data = self.nodes[1].getblock (auxblock['hash'])
    assert 'auxpow' in data
    auxJson = data['auxpow']
    assert_equal (auxJson['index'], 0)
    assert_equal (auxJson['parentblock'], apow[-160:])

    # Check that previous blocks don't have 'auxpow' in their getblock JSON.
    oldHash = self.nodes[1].getblockhash (100)
    data = self.nodes[1].getblock (oldHash)
    assert 'auxpow' not in data

    # Check that it paid correctly to the first node.
    t = self.nodes[0].listtransactions ("", 1)
    assert_equal (len (t), 1)
    t = t[0]
    assert_equal (t['category'], "immature")
    assert_equal (t['blockhash'], auxblock['hash'])
    assert t['generated']
    assert t['amount'] >= Decimal ("25")
    assert_equal (t['confirmations'], 1)

    # Verify the coinbase script.  Ensure that it includes the block height
    # to make the coinbase tx unique.  The expected block height is around
    # 200, so that the serialisation of the CScriptNum ends in an extra 00.
    # The vector has length 2, which makes up for 02XX00 as the serialised
    # height.  Check this.
    blk = self.nodes[1].getblock (auxblock['hash'])
    tx = self.nodes[1].getrawtransaction (blk['tx'][0], 1)
    coinbase = tx['vin'][0]['coinbase']
    assert_equal ("02%02x00" % auxblock['height'], coinbase[0 : 6])

    # Ensure that the payout address is changed from one block to the next.
    addr1 = self.getCoinbaseAddr (auxblock['hash'])
    newHash = auxpow.mineAuxpowBlock (self.nodes[0])
    self.sync_all ()
    addr2 = self.getCoinbaseAddr (newHash)
    assert addr1 != addr2
    valid = self.nodes[0].validateaddress (addr1)
    assert valid['ismine']
    valid = self.nodes[0].validateaddress (addr2)
    assert valid['ismine']
示例#18
0
    def test_common(self, create, submit):
        """
    Common test code that is shared between the tests for getauxblock and the
    createauxblock / submitauxblock method pair.
    """

        # Verify data that can be found in another way.
        auxblock = create()
        assert_equal(auxblock['chainid'], 1)
        assert_equal(auxblock['height'], self.nodes[0].getblockcount() + 1)
        assert_equal(auxblock['previousblockhash'],
                     self.nodes[0].getblockhash(auxblock['height'] - 1))

        # Calling again should give the same block.
        auxblock2 = create()
        assert_equal(auxblock2, auxblock)

        # If we receive a new block, the old hash will be replaced.
        self.sync_all()
        self.nodes[1].generate(1)
        self.sync_all()
        auxblock2 = create()
        assert auxblock['hash'] != auxblock2['hash']
        assert_raises_rpc_error(-8, 'block hash unknown', submit,
                                auxblock['hash'], "x")

        # Invalid format for auxpow.
        assert_raises_rpc_error(-1, None, submit, auxblock2['hash'], "x")

        # Invalidate the block again, send a transaction and query for the
        # auxblock to solve that contains the transaction.
        self.nodes[0].generate(1)
        addr = self.nodes[1].getnewaddress()
        txid = self.nodes[0].sendtoaddress(addr, 1)
        self.sync_all()
        assert_equal(self.nodes[1].getrawmempool(), [txid])
        auxblock = create()
        target = reverseHex(auxblock['_target'])

        # Cross-check target value with GBT to make explicitly sure that it is
        # correct (not just implicitly by successfully mining blocks for it
        # later on).
        gbt = self.nodes[0].getblocktemplate({"rules": ["segwit"]})
        assert_equal(target, gbt['target'].encode("ascii"))

        # Compute invalid auxpow.
        apow = computeAuxpow(auxblock['hash'], target, False)
        res = submit(auxblock['hash'], apow)
        assert not res

        # Compute and submit valid auxpow.
        apow = computeAuxpow(auxblock['hash'], target, True)
        res = submit(auxblock['hash'], apow)
        assert res

        # Make sure that the block is indeed accepted.
        self.sync_all()
        assert_equal(self.nodes[1].getrawmempool(), [])
        height = self.nodes[1].getblockcount()
        assert_equal(height, auxblock['height'])
        assert_equal(self.nodes[1].getblockhash(height), auxblock['hash'])

        # Call getblock and verify the auxpow field.
        data = self.nodes[1].getblock(auxblock['hash'])
        assert 'auxpow' in data
        auxJson = data['auxpow']
        assert_equal(auxJson['index'], 0)
        assert_equal(auxJson['chainindex'], 0)
        assert_equal(auxJson['merklebranch'], [])
        assert_equal(auxJson['chainmerklebranch'], [])
        assert_equal(auxJson['parentblock'], apow[-160:])

        # Also previous blocks should have 'auxpow', since all blocks (also
        # those generated by "generate") are merge-mined.
        oldHash = self.nodes[1].getblockhash(100)
        data = self.nodes[1].getblock(oldHash)
        assert 'auxpow' in data

        # Check that it paid correctly to the first node.
        t = self.nodes[0].listtransactions("*", 1)
        assert_equal(len(t), 1)
        t = t[0]
        assert_equal(t['category'], "immature")
        assert_equal(t['blockhash'], auxblock['hash'])
        assert t['generated']
        assert_greater_than_or_equal(t['amount'], Decimal("1"))
        assert_equal(t['confirmations'], 1)

        # Verify the coinbase script.  Ensure that it includes the block height
        # to make the coinbase tx unique.  The expected block height is around
        # 200, so that the serialisation of the CScriptNum ends in an extra 00.
        # The vector has length 2, which makes up for 02XX00 as the serialised
        # height.  Check this.  (With segwit, the height is different, so we skip
        # this for simplicity.)
        if not self.options.segwit:
            blk = self.nodes[1].getblock(auxblock['hash'])
            tx = self.nodes[1].getrawtransaction(blk['tx'][0], 1)
            coinbase = tx['vin'][0]['coinbase']
            assert_equal("02%02x00" % auxblock['height'], coinbase[0:6])
示例#19
0
  def run_test (self):
    BitcoinTestFramework.run_test (self)

    # Check for difficulty reports in various RPC calls.  Where the "current"
    # state is involved, we get two (for each algo).  Where a particular block
    # is involved, we just get that block's difficulty (whatever the algo).
    dual = []
    dual.append (self.nodes[0].getinfo ())
    dual.append (self.nodes[0].getblockchaininfo ())
    dual.append (self.nodes[0].getmininginfo ())
    for data in dual:
      assert 'difficulty_sha256d' in data
      assert 'difficulty_scrypt' in data
      assert 'difficulty' not in data
    bestHash = self.nodes[0].getbestblockhash ()
    data = self.nodes[0].getblock (bestHash)
    assert 'difficulty' in data
    assert 'difficulty_sha256d' not in data
    assert 'difficulty_scrypt' not in data

    # Check getdifficulty RPC call.
    diffSHA = self.nodes[0].getdifficulty (0)
    assert_equal (diffSHA, dual[0]['difficulty_sha256d'])
    diffScrypt = self.nodes[0].getdifficulty (1)
    assert_equal (diffScrypt, dual[0]['difficulty_scrypt'])
    try:
      self.nodes[0].getdifficulty ()
      raise AssertionError ("getdifficulty without arg accepted")
    except JSONRPCException as exc:
      assert_equal (exc.error['code'], -1)

    # Generate a few blocks with SHA256D.  Ensure that they are, indeed,
    # with the correct algo.
    arr1 = self.nodes[0].generate (5)
    arr2 = self.nodes[0].generate (5, 0)
    for blk in arr1 + arr2:
      data = self.nodes[0].getblock (blk)
      assert_equal (data['algo'], 0)

    # Generate a few blocks with scrypt.  Ensure the algo parameter.
    # Furthermore, at least one of them "should" have an obviously high
    # hash value.  It may, of course, happen that this is not the case,
    # but the probability for that is negligible (about 2^(-20)).
    arr = self.nodes[0].generate (20, 1)
    foundHigh = False
    for blk in arr:
      data = self.nodes[0].getblock (blk)
      assert_equal (data['algo'], 1)
      if blk[0] in '89abcdef':
        foundHigh = True
    assert foundHigh

    # Verify check for algo parameter.
    for p in [-1, 2]:
      try:
        self.nodes[0].generate (1, p)
        raise AssertionError ("invalid algo parameter accepted")
      except JSONRPCException as exc:
        assert_equal (exc.error['code'], -8)

    # Briefly test generatetoaddress as well.
    for algo in [0, 1]:
      addr = self.nodes[0].getnewaddress ()
      blkhash = self.nodes[0].generatetoaddress (1, addr, algo)
      assert_equal (1, len (blkhash))
      data = self.nodes[0].getblock(blkhash[0])
      assert_equal (algo, data['algo'])
      coinbaseTx = data['tx'][0]
      utxo = self.nodes[0].gettxout (coinbaseTx, 0)
      assert_equal ([addr], utxo['scriptPubKey']['addresses'])

    # Check updates of the returned block (or not) with getauxblock.
    # Note that this behaviour needs not necessarily be exactly as tested,
    # but the test ensures that no change is introduced accidentally.
    auxblock1 = self.nodes[0].getauxblock ()
    auxblock2 = self.nodes[0].getauxblock (0)
    assert_equal (auxblock1['hash'], auxblock2['hash'])
    auxblock2 = self.nodes[0].getauxblock (1)
    auxblock3 = self.nodes[0].getauxblock (1)
    assert_equal (auxblock2['hash'], auxblock3['hash'])
    assert auxblock2['hash'] != auxblock1['hash']
    auxblock3 = self.nodes[0].getauxblock ()
    assert auxblock1['hash'] != auxblock3['hash']

    # Use getauxblock with explicit algo to mine a SHA256D block.
    # Assert that this works (the block is saved) even if we request
    # another scrypt block before.
    auxblock = self.nodes[0].getauxblock ()
    assert_equal (auxblock['chainid'], 6)
    assert_equal (auxblock['algo'], 0)
    dummy = self.nodes[0].getauxblock (1)
    assert_equal (dummy['chainid'], 2)
    assert_equal (dummy['algo'], 1)

    # Solve the auxpow requested before.
    curcnt = self.nodes[0].getblockcount ()
    target = auxpow.reverseHex (auxblock['_target'])
    apow = auxpow.computeAuxpow (auxblock['hash'], target, True)
    res = self.nodes[0].getauxblock (auxblock['hash'], apow)
    assert res

    # Check submitted data.
    assert_equal (self.nodes[0].getblockcount (), curcnt + 1)
    data = self.nodes[0].getblock (auxblock['hash'])
    assert_equal (data['algo'], 0)

    # Mine an scrypt auxpow.  Since there is no built-in Python
    # function to scrypt, we do it differently:  Simply try submitting
    # until the block is accepted.  Since we need on average 2 trials,
    # this is no big hit.
    trials = 0
    curcnt = self.nodes[0].getblockcount ()
    ok = False
    while not ok:
      if trials > 100:
        raise AssertionError ("failed to merge-mine scrypt auxpow")
      trials += 1

      # Force an update of the block so we get a new trial.
      self.nodes[0].getauxblock (0)
      auxblock = self.nodes[0].getauxblock (1)

      target = auxpow.reverseHex (auxblock['_target'])
      apow = auxpow.computeAuxpow (auxblock['hash'], target, False)
      ok = self.nodes[0].getauxblock (auxblock['hash'], apow)
    print "Found scrypt block after %d trials." % trials

    # Check submitted auxblock.
    assert_equal (self.nodes[0].getblockcount (), curcnt + 1)
    data = self.nodes[0].getblock (auxblock['hash'])
    assert_equal (data['algo'], 1)