class ArmoryDTest(TiabTest):      
   def removeFileList(self, fileList):
      for f in fileList:
         if os.path.exists(f):
            os.remove(f)
      
   def armoryDTestCallback(self, action, args):
      if action == REFRESH_ACTION:
         self.walletIsScanned = True
         
   def setUp(self):
      
      self.verifyBlockHeight()
      self.fileA    = os.path.join(self.armoryHomeDir, 'armory_%s_.wallet' % TEST_WALLET_ID)
      self.fileB    = os.path.join(self.armoryHomeDir, 'armory_%s_backup.wallet' % TEST_WALLET_ID)
      self.fileAupd = os.path.join(self.armoryHomeDir, 'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID)
      self.fileBupd = os.path.join(self.armoryHomeDir, 'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID)

      self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd])
   
      # We need a controlled test, so we script the all the normally-random stuff
      self.privKey   = SecureBinaryData('\xaa'*32)
      self.privKey2  = SecureBinaryData('\x33'*32)
      self.chainstr  = SecureBinaryData('\xee'*32)
      theIV     = SecureBinaryData(hex_to_binary('77'*16))
      self.passphrase  = SecureBinaryData('A self.passphrase')
      self.passphrase2 = SecureBinaryData('A new self.passphrase')
      
      #register a callback
      TheBDM.registerCppNotification(self.armoryDTestCallback)

      #flag to check on wallet scan status
      self.walletIsScanned = False
      
      #create the wallet
      self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \
                                          plainRootKey=self.privKey, \
                                          chaincode=self.chainstr,   \
                                          IV=theIV, \
                                          shortLabel=TEST_WALLET_NAME, \
                                          longLabel=TEST_WALLET_DESCRIPTION,
                                          armoryHomeDir = self.armoryHomeDir)
      self.jsonServer = Armory_Json_Rpc_Server(self.wallet)
      
      #register it
      self.wallet.registerWallet()
      
      #wait on scan for 2 min then raise if the scan hasn't finished yet
      i = 0
      while not self.walletIsScanned:
         time.sleep(0.5)
         i += 1
         if i >= 60*4:
            raise RuntimeError("Timeout waiting for TheBDM to register the wallet.")
      
   def tearDown(self):
      TheBDM.unregisterCppNotification(self.armoryDTestCallback)
      self.wallet.unregisterWallet()
      self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd])
   

   # Can't test with actual transactions in this environment. See ARMORY-34.
   # This wallet has no txs
   # def testListunspent(self):
   #    actualResult = self.jsonServer.jsonrpc_listunspent()
   #    self.assertEqual(actualResult, [])
   def testImportprivkey(self):
      originalLength = len(self.wallet.linearAddr160List)
      self.jsonServer.jsonrpc_importprivkey(binary_to_hex(self.privKey2.toBinStr()))
      self.assertEqual(len(self.wallet.linearAddr160List), originalLength+1)

   def testGettxout(self):
      txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 0)
      self.assertEquals(txOut['value'],TX_ID1_OUTPUT0_VALUE)
      txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 1)
      self.assertEquals(txOut['value'],TX_ID1_OUTPUT1_VALUE)
         
   def testGetreceivedbyaddress(self):
      a160 = hash160(self.wallet.getNextUnusedAddress().binPublicKey65.toBinStr())
      testAddr = hash160_to_addrStr(a160)
      result = self.jsonServer.jsonrpc_getreceivedbyaddress(testAddr)
      self.assertEqual(result, 0)
      
   def testGetrawtransaction(self):
      actualRawTx = self.jsonServer.jsonrpc_getrawtransaction(TX_ID1)
      pyTx = PyTx().unserialize(hex_to_binary(actualRawTx))
      self.assertEquals(TX_ID1, binary_to_hex(pyTx.getHash(), BIGENDIAN))

   def testBackupWallet(self):
      backupTestPath = os.path.join(self.armoryHomeDir, 'armory_%s_.wallet.backup.test' % TEST_WALLET_ID)
      # Remove backupTestPath in case it exists
      backupFileList = [backupTestPath, self.fileB]
      self.removeFileList(backupFileList)
      # Remove the backup test path that is to be created after tear down.
      self.addCleanup(self.removeFileList, backupFileList)
      self.jsonServer.jsonrpc_backupwallet(backupTestPath)
      self.assertTrue(os.path.exists(backupTestPath))
      self.wallet.backupWalletFile()
      self.assertTrue(os.path.exists(self.fileB))
      
   def testDecoderawtransaction(self):
      actualDD = self.jsonServer.jsonrpc_decoderawtransaction(RAW_TX1)
      # Test specific values pulled from bitcoin daemon's output for the test raw TX
      expectScriptStr = 'OP_DUP OP_HASH160 PUSHDATA(20) [62d978319c7d7ac6cceed722c3d08aa81b371012] OP_EQUALVERIFY OP_CHECKSIG'
      self.assertEqual(actualDD['locktime'], 0)
      self.assertEqual(actualDD['version'], 1)
      self.assertEqual(len(actualDD['vin']), 1)
      self.assertEqual(actualDD['vin'][0]['sequence'], 4294967295L)
      self.assertEqual(actualDD['vin'][0]['scriptSig']['hex'], '4830450220081341a4e803c7c8e64c3a3fd285dca34c9f7c71c4dfc2b576d761c5783ce735022100eea66ba382d00e628d86fc5bc1928a93765e26fd8252c4d01efe22147c12b91a01410458fec9d580b0c6842cae00aecd96e89af3ff56f5be49dae425046e64057e0f499acc35ec10e1b544e0f01072296c6fa60a68ea515e59d24ff794cf8923cd30f4')
      self.assertEqual(actualDD['vin'][0]['vout'], 1)
      self.assertEqual(actualDD['vin'][0]['txid'], '04b865ecf5fca3a56f6ce73a571a09a668f4b7aa5a7547a5f51fae08eadcdbb5')
      self.assertEqual(len(actualDD['vout']), 2)
      self.assertEqual(actualDD['vout'][0]['value'], 20.0)
      self.assertEqual(actualDD['vout'][0]['n'], 0)
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['reqSigs'], 1)
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['hex'], '76a91462d978319c7d7ac6cceed722c3d08aa81b37101288ac')
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['addresses'], ['mpXd2u8fPVYdL1Nf9bZ4EFnqhkNyghGLxL'])
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['asm'], expectScriptStr)
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['type'], 'Standard (PKH)')
      self.assertEqual(actualDD['vout'][1]['scriptPubKey']['type'], 'Standard (PKH)')

   def testDumpprivkey(self):
      testPrivKey = self.privKey.toBinStr()
      hash160 = convertKeyDataToAddress(testPrivKey)
      addr58 = hash160_to_addrStr(hash160)
      
      # Verify that a bogus addrss Raises InvalidBitcoinAddress Exception
      result =  self.jsonServer.jsonrpc_dumpprivkey('bogus', 'hex')
      self.assertEqual(result['Error Type'],'InvalidBitcoinAddress')

      result =  self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex')
      self.assertEqual(result['Error Type'],'PrivateKeyNotFound')

      # verify that the first private key can be found
      firstHash160 = self.wallet.getNextUnusedAddress().getAddr160()
      firstAddr58 = hash160_to_addrStr(firstHash160)
      actualPrivateKeyHex = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \
                                                                'hex')
      actualPrivateKeyB58 = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \
                                                                'base58')
      self.privKey = self.wallet.getAddrByHash160(firstHash160).serializePlainPrivateKey()
      expectedPrivateKeyHex = binary_to_hex(self.privKey)
      expectedPrivateKeyB58 = privKey_to_base58(self.privKey)
      self.assertEqual(actualPrivateKeyHex, expectedPrivateKeyHex)
      self.assertEqual(actualPrivateKeyB58, expectedPrivateKeyB58)

      # Verify that a locked wallet Raises WalletUnlockNeeded Exception
      kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
      self.wallet.changeKdfParams(*kdfParams)
      self.wallet.changeWalletEncryption( securePassphrase=self.passphrase )
      self.wallet.lock()
      result = self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex')
      self.assertEqual(result['Error Type'],'WalletUnlockNeeded')
      
   def testEncryptwallet(self):
      kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
      self.wallet.changeKdfParams(*kdfParams)
      self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
      self.assertTrue(self.wallet.isLocked)
      
      # Verify that a locked wallet Raises WalletUnlockNeeded Exception
      # self.assertRaises(WalletUnlockNeeded, self.jsonServer.jsonrpc_encryptwallet, PASSPHRASE1)
      result = self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
      print result
      
   def testUnlockwallet(self):
      kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
      self.wallet.changeKdfParams(*kdfParams)
      self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
      self.assertTrue(self.wallet.isLocked)
      self.jsonServer.jsonrpc_walletpassphrase(PASSPHRASE1, UNLOCK_TIMEOUT)
      self.assertFalse(self.wallet.isLocked)
      time.sleep(UNLOCK_TIMEOUT+1)
      self.wallet.checkWalletLockTimeout()
      self.assertTrue(self.wallet.isLocked)
      
   def testGetWalletInfo(self):
      wltInfo = self.jsonServer.jsonrpc_getwalletinfo()
      self.assertEqual(wltInfo['name'], TEST_WALLET_NAME)
      self.assertEqual(wltInfo['description'], TEST_WALLET_DESCRIPTION)
      self.assertEqual(wltInfo['balance'], AmountToJSON(self.wallet.getBalance('Spend')))
      self.assertEqual(wltInfo['keypoolsize'], self.wallet.addrPoolSize)
      self.assertEqual(wltInfo['numaddrgen'], len(self.wallet.addrMap))
      self.assertEqual(wltInfo['highestusedindex'], self.wallet.highestUsedChainIndex)
   
   # This should always return 0 balance
   # Need to create our own test net to test with balances
   def testGetBalance(self):
      for ballanceType in ['spendable','spend', 'unconf', \
                           'unconfirmed', 'total', 'ultimate','unspent', 'full']:
         self.assertEqual(self.jsonServer.jsonrpc_getbalance(ballanceType),
                          AmountToJSON(self.wallet.getBalance(ballanceType)))
Esempio n. 2
0
class ArmoryDTest(TiabTest):
    def removeFileList(self, fileList):
        for f in fileList:
            if os.path.exists(f):
                os.remove(f)

    def armoryDTestCallback(self, action, args):
        if action == REFRESH_ACTION:
            self.walletIsScanned = True

    def setUp(self):

        self.verifyBlockHeight()
        self.fileA = os.path.join(self.armoryHomeDir,
                                  'armory_%s_.wallet' % TEST_WALLET_ID)
        self.fileB = os.path.join(self.armoryHomeDir,
                                  'armory_%s_backup.wallet' % TEST_WALLET_ID)
        self.fileAupd = os.path.join(
            self.armoryHomeDir,
            'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID)
        self.fileBupd = os.path.join(
            self.armoryHomeDir,
            'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID)

        self.removeFileList(
            [self.fileA, self.fileB, self.fileAupd, self.fileBupd])

        # We need a controlled test, so we script the all the normally-random stuff
        self.privKey = SecureBinaryData('\xaa' * 32)
        self.privKey2 = SecureBinaryData('\x33' * 32)
        self.chainstr = SecureBinaryData('\xee' * 32)
        theIV = SecureBinaryData(hex_to_binary('77' * 16))
        self.passphrase = SecureBinaryData('A self.passphrase')
        self.passphrase2 = SecureBinaryData('A new self.passphrase')

        #register a callback
        TheBDM.registerCppNotification(self.armoryDTestCallback)

        #flag to check on wallet scan status
        self.walletIsScanned = False

        #create the wallet
        self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \
                                            plainRootKey=self.privKey, \
                                            chaincode=self.chainstr,   \
                                            IV=theIV, \
                                            shortLabel=TEST_WALLET_NAME, \
                                            longLabel=TEST_WALLET_DESCRIPTION,
                                            armoryHomeDir = self.armoryHomeDir)
        self.jsonServer = Armory_Json_Rpc_Server(self.wallet)

        #register it
        self.wallet.registerWallet()

        #wait on scan for 2 min then raise if the scan hasn't finished yet
        i = 0
        while not self.walletIsScanned:
            time.sleep(0.5)
            i += 1
            if i >= 60 * 4:
                raise RuntimeError(
                    "Timeout waiting for TheBDM to register the wallet.")

    def tearDown(self):
        TheBDM.unregisterCppNotification(self.armoryDTestCallback)
        self.wallet.unregisterWallet()
        self.removeFileList(
            [self.fileA, self.fileB, self.fileAupd, self.fileBupd])

    # Can't test with actual transactions in this environment. See ARMORY-34.
    # This wallet has no txs
    # def testListunspent(self):
    #    actualResult = self.jsonServer.jsonrpc_listunspent()
    #    self.assertEqual(actualResult, [])
    def testImportprivkey(self):
        originalLength = len(self.wallet.linearAddr160List)
        self.jsonServer.jsonrpc_importprivkey(
            binary_to_hex(self.privKey2.toBinStr()))
        self.assertEqual(len(self.wallet.linearAddr160List),
                         originalLength + 1)

    # Requires Supernode
    @SkipTest
    def testGettxout(self):
        txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 0)
        self.assertEquals(txOut['value'], TX_ID1_OUTPUT0_VALUE)
        txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 1)
        self.assertEquals(txOut['value'], TX_ID1_OUTPUT1_VALUE)

    def testGetreceivedbyaddress(self):
        a160 = hash160(
            self.wallet.getNextUnusedAddress().binPublicKey65.toBinStr())
        testAddr = hash160_to_addrStr(a160)
        result = self.jsonServer.jsonrpc_getreceivedbyaddress(testAddr)
        self.assertEqual(result, 0)

    # Requires Supernode
    @SkipTest
    def testGetrawtransaction(self):
        actualRawTx = self.jsonServer.jsonrpc_getrawtransaction(TX_ID1)
        pyTx = PyTx().unserialize(hex_to_binary(actualRawTx))
        self.assertEquals(TX_ID1, binary_to_hex(pyTx.getHash(), BIGENDIAN))

    def testBackupWallet(self):
        backupTestPath = os.path.join(
            self.armoryHomeDir,
            'armory_%s_.wallet.backup.test' % TEST_WALLET_ID)
        # Remove backupTestPath in case it exists
        backupFileList = [backupTestPath, self.fileB]
        self.removeFileList(backupFileList)
        # Remove the backup test path that is to be created after tear down.
        self.addCleanup(self.removeFileList, backupFileList)
        self.jsonServer.jsonrpc_backupwallet(backupTestPath)
        self.assertTrue(os.path.exists(backupTestPath))
        self.wallet.backupWalletFile()
        self.assertTrue(os.path.exists(self.fileB))

    def testDecoderawtransaction(self):
        actualDD = self.jsonServer.jsonrpc_decoderawtransaction(RAW_TX1)
        # Test specific values pulled from bitcoin daemon's output for the test raw TX
        expectScriptStr = 'OP_DUP OP_HASH160 PUSHDATA(20) [62d978319c7d7ac6cceed722c3d08aa81b371012] OP_EQUALVERIFY OP_CHECKSIG'
        self.assertEqual(actualDD['locktime'], 0)
        self.assertEqual(actualDD['version'], 1)
        self.assertEqual(len(actualDD['vin']), 1)
        self.assertEqual(actualDD['vin'][0]['sequence'], 4294967295L)
        self.assertEqual(
            actualDD['vin'][0]['scriptSig']['hex'],
            '4830450220081341a4e803c7c8e64c3a3fd285dca34c9f7c71c4dfc2b576d761c5783ce735022100eea66ba382d00e628d86fc5bc1928a93765e26fd8252c4d01efe22147c12b91a01410458fec9d580b0c6842cae00aecd96e89af3ff56f5be49dae425046e64057e0f499acc35ec10e1b544e0f01072296c6fa60a68ea515e59d24ff794cf8923cd30f4'
        )
        self.assertEqual(actualDD['vin'][0]['vout'], 1)
        self.assertEqual(
            actualDD['vin'][0]['txid'],
            '04b865ecf5fca3a56f6ce73a571a09a668f4b7aa5a7547a5f51fae08eadcdbb5')
        self.assertEqual(len(actualDD['vout']), 2)
        self.assertEqual(actualDD['vout'][0]['value'], 20.0)
        self.assertEqual(actualDD['vout'][0]['n'], 0)
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['reqSigs'], 1)
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['hex'],
                         '76a91462d978319c7d7ac6cceed722c3d08aa81b37101288ac')
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['addresses'],
                         ['mpXd2u8fPVYdL1Nf9bZ4EFnqhkNyghGLxL'])
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['asm'],
                         expectScriptStr)
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['type'],
                         'Standard (PKH)')
        self.assertEqual(actualDD['vout'][1]['scriptPubKey']['type'],
                         'Standard (PKH)')

    def testDumpprivkey(self):
        testPrivKey = self.privKey.toBinStr()
        hash160 = convertKeyDataToAddress(testPrivKey)
        addr58 = hash160_to_addrStr(hash160)

        # Verify that a bogus addrss Raises InvalidBitcoinAddress Exception
        result = self.jsonServer.jsonrpc_dumpprivkey('bogus', 'hex')
        self.assertEqual(result['Error Type'], 'InvalidBitcoinAddress')

        result = self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex')
        self.assertEqual(result['Error Type'], 'PrivateKeyNotFound')

        # verify that the first private key can be found
        firstHash160 = self.wallet.getNextUnusedAddress().getAddr160()
        firstAddr58 = hash160_to_addrStr(firstHash160)
        actualPrivateKeyHex = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \
                                                                  'hex')
        actualPrivateKeyB58 = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \
                                                                  'base58')
        self.privKey = self.wallet.getAddrByHash160(
            firstHash160).serializePlainPrivateKey()
        expectedPrivateKeyHex = binary_to_hex(self.privKey)
        expectedPrivateKeyB58 = privKey_to_base58(self.privKey)
        self.assertEqual(actualPrivateKeyHex, expectedPrivateKeyHex)
        self.assertEqual(actualPrivateKeyB58, expectedPrivateKeyB58)

        # Verify that a locked wallet Raises WalletUnlockNeeded Exception
        kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
        self.wallet.changeKdfParams(*kdfParams)
        self.wallet.changeWalletEncryption(securePassphrase=self.passphrase)
        self.wallet.lock()
        result = self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex')
        self.assertEqual(result['Error Type'], 'WalletUnlockNeeded')

    def testEncryptwallet(self):
        kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
        self.wallet.changeKdfParams(*kdfParams)
        self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
        self.assertTrue(self.wallet.isLocked)

        # Verify that a locked wallet Raises WalletUnlockNeeded Exception
        # self.assertRaises(WalletUnlockNeeded, self.jsonServer.jsonrpc_encryptwallet, PASSPHRASE1)
        result = self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
        print result

    def testUnlockwallet(self):
        kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
        self.wallet.changeKdfParams(*kdfParams)
        self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
        self.assertTrue(self.wallet.isLocked)
        self.jsonServer.jsonrpc_walletpassphrase(PASSPHRASE1, UNLOCK_TIMEOUT)
        self.assertFalse(self.wallet.isLocked)
        time.sleep(UNLOCK_TIMEOUT + 1)
        self.wallet.checkWalletLockTimeout()
        self.assertTrue(self.wallet.isLocked)

    def testGetWalletInfo(self):
        wltInfo = self.jsonServer.jsonrpc_getwalletinfo()
        self.assertEqual(wltInfo['name'], TEST_WALLET_NAME)
        self.assertEqual(wltInfo['description'], TEST_WALLET_DESCRIPTION)
        self.assertEqual(wltInfo['balance'],
                         AmountToJSON(self.wallet.getBalance('Spend')))
        self.assertEqual(wltInfo['keypoolsize'], self.wallet.addrPoolSize)
        self.assertEqual(wltInfo['numaddrgen'], len(self.wallet.addrMap))
        self.assertEqual(wltInfo['highestusedindex'],
                         self.wallet.highestUsedChainIndex)

    # This should always return 0 balance
    # Need to create our own test net to test with balances
    def testGetBalance(self):
        for ballanceType in ['spendable','spend', 'unconf', \
                             'unconfirmed', 'total', 'ultimate','unspent', 'full']:
            self.assertEqual(
                self.jsonServer.jsonrpc_getbalance(ballanceType),
                AmountToJSON(self.wallet.getBalance(ballanceType)))
   def testWalletRecovery(self):
      #run recovery on broken wallet
      recThread = PyBtcWalletRecovery().RecoverWallet(self.corruptWallet, \
                                                      'testing', RECOVERMODE.Full, \
                                                      returnError = 'Dict')
      recThread.join()
      brkWltResult = recThread.output
      
      self.assertTrue(len(brkWltResult['sequenceGaps'])==1, \
                      "Sequence Gap Undetected")
      self.assertTrue(len(brkWltResult['forkedPublicKeyChain'])==3, \
                      "Address Chain Forks Undetected")
      self.assertTrue(len(brkWltResult['unmatchedPair'])==100, \
                      "Unmatched Priv/Pub Key Undetected")
      self.assertTrue(len(brkWltResult['misc'])==50, \
                      "Wallet Encryption Inconsistency Undetected")
      self.assertTrue(len(brkWltResult['importedErr'])==50, \
                      "Unexpected Errors Found")         
      self.assertTrue(brkWltResult['nErrors']==204, \
                      "Unexpected Errors Found")   
      
      #check obfuscated keys yield the valid key
      #grab root key
      badWlt = PyBtcWallet()
      badWlt.readWalletFile(self.corruptWallet, False, False)
      rootAddr = badWlt.addrMap['ROOT']
      
      SecurePassphrase = SecureBinaryData('testing')
      secureKdfOutput = badWlt.kdf.DeriveKey(SecurePassphrase)
      
      #HMAC Q
      rootAddr.unlock(secureKdfOutput)
      Q = rootAddr.binPrivKey32_Plain.toBinStr()
      
      nonce = 0
      while 1:
         hmacQ = HMAC256(Q, 'LogMult%d' % nonce)
         if binary_to_int(hmacQ, BIGENDIAN) < SECP256K1_ORDER:         
            hmacQ = SecureBinaryData(hmacQ)
            break
         nonce = nonce +1
      
      #Bad Private Keys
      import operator
      badKeys = [addrObj for addrObj in (sorted(badWlt.addrMap.values(), 
                             key=operator.attrgetter('chainIndex')))]
         
      #run through obdsPrivKey
      for i in range(0, len(brkWltResult['privMult'])):
         obfsPKey = SecureBinaryData(
                        hex_to_binary(brkWltResult['privMult'][i]))
         pKey = CryptoECDSA().ECMultiplyScalars(obfsPKey.toBinStr(), \
                                                hmacQ.toBinStr())
         
         try:
            badKeys[i+201].unlock(secureKdfOutput)
         except:
            continue
         
         self.assertTrue(binary_to_hex(pKey) == \
                         badKeys[i+201].binPrivKey32_Plain.toHexStr(), \
                         'key mult error')
      
      #run recovery on recovered wallet
      recThread = PyBtcWalletRecovery().RecoverWallet( \
                                 'armory_%s_RECOVERED.wallet' % self.wltID, \
                                 'testing', RECOVERMODE.Full, \
                                 returnError = 'Dict')
      recThread.join()
      rcvWltResult = recThread.output
      
      self.assertTrue(len(rcvWltResult['importedErr'])==50, \
                      "Unexpected Errors Found")         
      self.assertTrue(rcvWltResult['nErrors']==50, \
                      "Unexpected Errors Found")   
      self.assertTrue(len(rcvWltResult['negativeImports'])==99, \
                      "Missing neg Imports")
      
# Running tests with "python <module name>" will NOT work for any Armory tests
# You must run tests with "python -m unittest <module name>" or run all tests with "python -m unittest discover"
# if __name__ == "__main__":
#    unittest.main()
Esempio n. 4
0
    def testWalletRecovery(self):
        #run recovery on broken wallet
        recThread = PyBtcWalletRecovery().RecoverWallet(self.corruptWallet, \
                                                        'testing', RECOVERMODE.Full, \
                                                        returnError = 'Dict')
        recThread.join()
        brkWltResult = recThread.output

        self.assertTrue(len(brkWltResult['sequenceGaps'])==1, \
                        "Sequence Gap Undetected")
        self.assertTrue(len(brkWltResult['forkedPublicKeyChain'])==3, \
                        "Address Chain Forks Undetected")
        self.assertTrue(len(brkWltResult['unmatchedPair'])==100, \
                        "Unmatched Priv/Pub Key Undetected")
        self.assertTrue(len(brkWltResult['misc'])==50, \
                        "Wallet Encryption Inconsistency Undetected")
        self.assertTrue(len(brkWltResult['importedErr'])==50, \
                        "Unexpected Errors Found")
        self.assertTrue(brkWltResult['nErrors']==204, \
                        "Unexpected Errors Found")

        #check obfuscated keys yield the valid key
        #grab root key
        badWlt = PyBtcWallet()
        badWlt.readWalletFile(self.corruptWallet, False, False)
        rootAddr = badWlt.addrMap['ROOT']

        SecurePassphrase = SecureBinaryData('testing')
        secureKdfOutput = badWlt.kdf.DeriveKey(SecurePassphrase)

        #HMAC Q
        rootAddr.unlock(secureKdfOutput)
        Q = rootAddr.binPrivKey32_Plain.toBinStr()

        nonce = 0
        while 1:
            hmacQ = HMAC256(Q, 'LogMult%d' % nonce)
            if binary_to_int(hmacQ, BIGENDIAN) < SECP256K1_ORDER:
                hmacQ = SecureBinaryData(hmacQ)
                break
            nonce = nonce + 1

        #Bad Private Keys
        import operator
        badKeys = [
            addrObj
            for addrObj in (sorted(badWlt.addrMap.values(),
                                   key=operator.attrgetter('chainIndex')))
        ]

        #run through obdsPrivKey
        for i in range(0, len(brkWltResult['privMult'])):
            obfsPKey = SecureBinaryData(
                hex_to_binary(brkWltResult['privMult'][i]))
            pKey = CryptoECDSA().ECMultiplyScalars(obfsPKey.toBinStr(), \
                                                   hmacQ.toBinStr())

            try:
                badKeys[i + 201].unlock(secureKdfOutput)
            except:
                continue

            self.assertTrue(binary_to_hex(pKey) == \
                            badKeys[i+201].binPrivKey32_Plain.toHexStr(), \
                            'key mult error')

        #run recovery on recovered wallet
        recThread = PyBtcWalletRecovery().RecoverWallet( \
                                   'armory_%s_RECOVERED.wallet' % self.wltID, \
                                   'testing', RECOVERMODE.Full, \
                                   returnError = 'Dict')
        recThread.join()
        rcvWltResult = recThread.output

        self.assertTrue(len(rcvWltResult['importedErr'])==50, \
                        "Unexpected Errors Found")
        self.assertTrue(rcvWltResult['nErrors']==50, \
                        "Unexpected Errors Found")
        self.assertTrue(len(rcvWltResult['negativeImports'])==99, \
                        "Missing neg Imports")


# Running tests with "python <module name>" will NOT work for any Armory tests
# You must run tests with "python -m unittest <module name>" or run all tests with "python -m unittest discover"
# if __name__ == "__main__":
#    unittest.main()
Esempio n. 5
0
class ArmoryDTest(unittest.TestCase):
    def removeFileList(self, fileList):
        for f in fileList:
            if os.path.exists(f):
                os.remove(f)

    @classmethod
    def setUpClass(self):
        # This is not a UI so no need to worry about the main thread being blocked.
        # Any UI that uses this Daemon can put the call to the Daemon on it's own thread.
        TheBDM.setBlocking(True)
        TheBDM.setOnlineMode(True)
        while not TheBDM.getBDMState() == 'BlockchainReady':
            time.sleep(2)

    def setUp(self):
        self.fileA = os.path.join(ARMORY_HOME_DIR,
                                  'armory_%s_.wallet' % TEST_WALLET_ID)
        self.fileB = os.path.join(ARMORY_HOME_DIR,
                                  'armory_%s_backup.wallet' % TEST_WALLET_ID)
        self.fileAupd = os.path.join(
            ARMORY_HOME_DIR,
            'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID)
        self.fileBupd = os.path.join(
            ARMORY_HOME_DIR,
            'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID)

        self.removeFileList(
            [self.fileA, self.fileB, self.fileAupd, self.fileBupd])

        # We need a controlled test, so we script the all the normally-random stuff
        self.privKey = SecureBinaryData('\xaa' * 32)
        self.privKey2 = SecureBinaryData('\x33' * 32)
        self.chainstr = SecureBinaryData('\xee' * 32)
        theIV = SecureBinaryData(hex_to_binary('77' * 16))
        self.passphrase = SecureBinaryData('A self.passphrase')
        self.passphrase2 = SecureBinaryData('A new self.passphrase')

        self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \
                                            plainRootKey=self.privKey, \
                                            chaincode=self.chainstr,   \
                                            IV=theIV, \
                                            shortLabel=TEST_WALLET_NAME, \
                                            longLabel=TEST_WALLET_DESCRIPTION)
        self.jsonServer = Armory_Json_Rpc_Server(self.wallet)
        TheBDM.registerWallet(self.wallet)

    def tearDown(self):
        self.removeFileList(
            [self.fileA, self.fileB, self.fileAupd, self.fileBupd])

    # Can't test with actual transactions in this environment. See ARMORY-34.
    # This wallet has no txs
    def testListunspent(self):
        actualResult = self.jsonServer.jsonrpc_listunspent()
        self.assertEqual(actualResult, [])

    def testImportprivkey(self):
        originalLength = len(self.wallet.linearAddr160List)
        self.jsonServer.jsonrpc_importprivkey(self.privKey2)
        self.assertEqual(len(self.wallet.linearAddr160List),
                         originalLength + 1)

    def testGettxout(self):
        txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 0)
        self.assertEquals(TX_ID1_OUTPUT0_VALUE, txOut.value)
        txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 1)
        self.assertEquals(TX_ID1_OUTPUT1_VALUE, txOut.value)

    # Cannot unit test actual balances. Only verify that getreceivedbyaddress return a 0 result.
    def testGetreceivedbyaddress(self):
        a160 = hash160(
            self.wallet.getNextUnusedAddress().binPublicKey65.toBinStr())
        testAddr = hash160_to_addrStr(a160)
        result = self.jsonServer.jsonrpc_getreceivedbyaddress(testAddr)
        self.assertEqual(result, 0)

    def testGetrawtransaction(self):
        actualRawTx = self.jsonServer.jsonrpc_getrawtransaction(TX_ID1)
        pyTx = PyTx().unserialize(hex_to_binary(actualRawTx))
        self.assertEquals(TX_ID1, binary_to_hex(pyTx.getHash(), BIGENDIAN))

    def testBackupWallet(self):
        backupTestPath = os.path.join(
            ARMORY_HOME_DIR, 'armory_%s_.wallet.backup.test' % TEST_WALLET_ID)
        # Remove backupTestPath in case it exists
        backupFileList = [backupTestPath, self.fileB]
        self.removeFileList(backupFileList)
        # Remove the backup test path that is to be created after tear down.
        self.addCleanup(self.removeFileList, backupFileList)
        self.jsonServer.jsonrpc_backupwallet(backupTestPath)
        self.assertTrue(os.path.exists(backupTestPath))
        self.wallet.backupWalletFile()
        self.assertTrue(os.path.exists(self.fileB))

    def testDecoderawtransaction(self):
        actualDD = self.jsonServer.jsonrpc_decoderawtransaction(RAW_TX1)
        # Test specific values pulled from bitcoin daemon's output for the test raw TX
        expectScriptStr = 'OP_DUP OP_HASH160 PUSHDATA(20) [be17ec0fc1f8aa029223dbe5f53109d0faf8c797] OP_EQUALVERIFY OP_CHECKSIG'
        self.assertEqual(actualDD['locktime'], 0)
        self.assertEqual(actualDD['version'], 1)
        self.assertEqual(actualDD['vin'][0]['sequence'], 4294967295L)
        self.assertEqual(actualDD['vin'][0]['scriptSig']['hex'], '')
        self.assertEqual(actualDD['vin'][0]['scriptSig']['asm'], '')
        self.assertEqual(actualDD['vin'][0]['vout'], 1201)
        self.assertEqual(
            actualDD['vin'][0]['txid'],
            'e450dc7394f8432d89c68d0df6a5506cb81eac60c977bfc7932633aaf835a31f')
        self.assertEqual(actualDD['vin'][1]['vout'], 294)
        self.assertEqual(
            actualDD['vin'][1]['txid'],
            '8867f0f84e80588ed00a05e604487442546ef42ab4c93445a09b00a6d487e74b')
        self.assertEqual(actualDD['vout'][0]['value'], 0.0001944)
        self.assertEqual(actualDD['vout'][0]['n'], 0)
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['reqSigs'], 1)
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['hex'],
                         '76a914be17ec0fc1f8aa029223dbe5f53109d0faf8c79788ac')
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['addresses'],
                         ['mxr5Le3bt7dfbFqmpK6saUYPt5xtcDB7Yw'])
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['asm'],
                         expectScriptStr)
        self.assertEqual(actualDD['vout'][0]['scriptPubKey']['type'],
                         'Standard (PKH)')
        self.assertEqual(actualDD['vout'][1]['scriptPubKey']['type'],
                         'Standard (PKH)')
        self.assertEqual(actualDD['vout'][2]['scriptPubKey']['type'],
                         'Non-Standard')

    def testDumpprivkey(self):

        testPrivKey = self.privKey.toBinStr()
        hash160 = convertKeyDataToAddress(testPrivKey)
        addr58 = hash160_to_addrStr(hash160)

        # Verify that a bogus addrss Raises InvalidBitcoinAddress Exception
        self.assertRaises(InvalidBitcoinAddress,
                          self.jsonServer.jsonrpc_dumpprivkey, 'bogus')

        # verify that the root private key is not found
        self.assertRaises(PrivateKeyNotFound,
                          self.jsonServer.jsonrpc_dumpprivkey, addr58)

        # verify that the first private key can be found
        firstHash160 = self.wallet.getNextUnusedAddress().getAddr160()
        firstAddr58 = hash160_to_addrStr(firstHash160)
        actualPrivateKey = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58)
        expectedPrivateKey = self.wallet.getAddrByHash160(
            firstHash160).serializePlainPrivateKey()
        self.assertEqual(actualPrivateKey, expectedPrivateKey)

        # Verify that a locked wallet Raises WalletUnlockNeeded Exception
        kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
        self.wallet.changeKdfParams(*kdfParams)
        self.wallet.changeWalletEncryption(securePassphrase=self.passphrase)
        self.wallet.lock()
        self.assertRaises(WalletUnlockNeeded,
                          self.jsonServer.jsonrpc_dumpprivkey, addr58)

    def testEncryptwallet(self):
        kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
        self.wallet.changeKdfParams(*kdfParams)
        self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
        self.assertTrue(self.wallet.isLocked)

        # Verify that a locked wallet Raises WalletUnlockNeeded Exception
        self.assertRaises(WalletUnlockNeeded,
                          self.jsonServer.jsonrpc_encryptwallet, PASSPHRASE1)

    def testUnlockwallet(self):
        kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
        self.wallet.changeKdfParams(*kdfParams)
        self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
        self.assertTrue(self.wallet.isLocked)
        self.jsonServer.jsonrpc_unlockwallet(PASSPHRASE1, UNLOCK_TIMEOUT)
        self.assertFalse(self.wallet.isLocked)
        time.sleep(UNLOCK_TIMEOUT + 1)
        self.wallet.checkWalletLockTimeout()
        self.assertTrue(self.wallet.isLocked)

    def testGetWalletInfo(self):
        wltInfo = self.jsonServer.jsonrpc_getwalletinfo()
        self.assertEqual(wltInfo['name'], TEST_WALLET_NAME)
        self.assertEqual(wltInfo['description'], TEST_WALLET_DESCRIPTION)
        self.assertEqual(wltInfo['balance'],
                         AmountToJSON(self.wallet.getBalance('Spend')))
        self.assertEqual(wltInfo['keypoolsize'], self.wallet.addrPoolSize)
        self.assertEqual(wltInfo['numaddrgen'], len(self.wallet.addrMap))
        self.assertEqual(wltInfo['highestusedindex'],
                         self.wallet.highestUsedChainIndex)

    # This should always return 0 balance
    # Need to create our own test net to test with balances
    def testGetBalance(self):
        for ballanceType in ['spendable','spend', 'unconf', \
                             'unconfirmed', 'total', 'ultimate','unspent', 'full']:
            self.assertEqual(
                self.jsonServer.jsonrpc_getbalance(ballanceType),
                AmountToJSON(self.wallet.getBalance(ballanceType)))
        self.assertEqual(self.jsonServer.jsonrpc_getbalance('bogus'), -1)
Esempio n. 6
0
class ArmoryDTest(unittest.TestCase):      
   def removeFileList(self, fileList):
      for f in fileList:
         if os.path.exists(f):
            os.remove(f)
            
   @classmethod
   def setUpClass(self):
      # This is not a UI so no need to worry about the main thread being blocked.
      # Any UI that uses this Daemon can put the call to the Daemon on it's own thread.
      TheBDM.Reset()
      TheBDM.setBlocking(True)
      TheBDM.setOnlineMode(True)
      while not TheBDM.getBDMState()=='BlockchainReady':
         time.sleep(2)

   def setUp(self):
      self.fileA    = os.path.join(ARMORY_HOME_DIR, 'armory_%s_.wallet' % TEST_WALLET_ID)
      self.fileB    = os.path.join(ARMORY_HOME_DIR, 'armory_%s_backup.wallet' % TEST_WALLET_ID)
      self.fileAupd = os.path.join(ARMORY_HOME_DIR, 'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID)
      self.fileBupd = os.path.join(ARMORY_HOME_DIR, 'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID)

      self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd])
   
      # We need a controlled test, so we script the all the normally-random stuff
      self.privKey   = SecureBinaryData('\xaa'*32)
      self.privKey2  = SecureBinaryData('\x33'*32)
      self.chainstr  = SecureBinaryData('\xee'*32)
      theIV     = SecureBinaryData(hex_to_binary('77'*16))
      self.passphrase  = SecureBinaryData('A self.passphrase')
      self.passphrase2 = SecureBinaryData('A new self.passphrase')
      
      self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \
                                          plainRootKey=self.privKey, \
                                          chaincode=self.chainstr,   \
                                          IV=theIV, \
                                          shortLabel=TEST_WALLET_NAME, \
                                          longLabel=TEST_WALLET_DESCRIPTION)
      self.jsonServer = Armory_Json_Rpc_Server(self.wallet)
      TheBDM.registerWallet(self.wallet)
      
   def tearDown(self):
      self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd])
   

   # Can't test with actual transactions in this environment. See ARMORY-34.
   # This wallet has no txs
   # def testListunspent(self):
   #    actualResult = self.jsonServer.jsonrpc_listunspent()
   #    self.assertEqual(actualResult, [])
      
   def testImportprivkey(self):
      originalLength = len(self.wallet.linearAddr160List)
      self.jsonServer.jsonrpc_importprivkey(self.privKey2)
      self.assertEqual(len(self.wallet.linearAddr160List), originalLength+1)
      
   def testGettxout(self):
      txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 0)
      self.assertEquals(TX_ID1_OUTPUT0_VALUE, txOut.value)
      txOut = self.jsonServer.jsonrpc_gettxout(TX_ID1, 1)
      self.assertEquals(TX_ID1_OUTPUT1_VALUE, txOut.value)
         
   # Cannot unit test actual balances. Only verify that getreceivedbyaddress return a 0 result.
   def testGetreceivedbyaddress(self):
      a160 = hash160(self.wallet.getNextUnusedAddress().binPublicKey65.toBinStr())
      testAddr = hash160_to_addrStr(a160)
      result = self.jsonServer.jsonrpc_getreceivedbyaddress(testAddr)
      self.assertEqual(result, 0)
      
   def testGetrawtransaction(self):
      actualRawTx = self.jsonServer.jsonrpc_getrawtransaction(TX_ID1)
      pyTx = PyTx().unserialize(hex_to_binary(actualRawTx))
      self.assertEquals(TX_ID1, binary_to_hex(pyTx.getHash(), BIGENDIAN))

   def testBackupWallet(self):
      backupTestPath = os.path.join(ARMORY_HOME_DIR, 'armory_%s_.wallet.backup.test' % TEST_WALLET_ID)
      # Remove backupTestPath in case it exists
      backupFileList = [backupTestPath, self.fileB]
      self.removeFileList(backupFileList)
      # Remove the backup test path that is to be created after tear down.
      self.addCleanup(self.removeFileList, backupFileList)
      self.jsonServer.jsonrpc_backupwallet(backupTestPath)
      self.assertTrue(os.path.exists(backupTestPath))
      self.wallet.backupWalletFile()
      self.assertTrue(os.path.exists(self.fileB))
      
   def testDecoderawtransaction(self):
      actualDD = self.jsonServer.jsonrpc_decoderawtransaction(RAW_TX1)
      # Test specific values pulled from bitcoin daemon's output for the test raw TX
      expectScriptStr = 'OP_DUP OP_HASH160 PUSHDATA(20) [be17ec0fc1f8aa029223dbe5f53109d0faf8c797] OP_EQUALVERIFY OP_CHECKSIG'
      self.assertEqual(actualDD['locktime'], 0)
      self.assertEqual(actualDD['version'], 1)
      self.assertEqual(actualDD['vin'][0]['sequence'], 4294967295L)
      self.assertEqual(actualDD['vin'][0]['scriptSig']['hex'], '')
      self.assertEqual(actualDD['vin'][0]['scriptSig']['asm'], '')
      self.assertEqual(actualDD['vin'][0]['vout'], 1201)
      self.assertEqual(actualDD['vin'][0]['txid'], 'e450dc7394f8432d89c68d0df6a5506cb81eac60c977bfc7932633aaf835a31f')
      self.assertEqual(actualDD['vin'][1]['vout'], 294)
      self.assertEqual(actualDD['vin'][1]['txid'], '8867f0f84e80588ed00a05e604487442546ef42ab4c93445a09b00a6d487e74b')
      self.assertEqual(actualDD['vout'][0]['value'], 0.0001944)
      self.assertEqual(actualDD['vout'][0]['n'], 0)
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['reqSigs'], 1)
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['hex'], '76a914be17ec0fc1f8aa029223dbe5f53109d0faf8c79788ac')
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['addresses'], ['mxr5Le3bt7dfbFqmpK6saUYPt5xtcDB7Yw'])
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['asm'], expectScriptStr)
      self.assertEqual(actualDD['vout'][0]['scriptPubKey']['type'], 'Standard (PKH)')
      self.assertEqual(actualDD['vout'][1]['scriptPubKey']['type'], 'Standard (PKH)')
      self.assertEqual(actualDD['vout'][2]['scriptPubKey']['type'], 'Non-Standard')
      
      
   def testDumpprivkey(self):

      testPrivKey = self.privKey.toBinStr()
      hash160 = convertKeyDataToAddress(testPrivKey)
      addr58 = hash160_to_addrStr(hash160)
      
      # Verify that a bogus addrss Raises InvalidBitcoinAddress Exception
      self.assertRaises(InvalidBitcoinAddress, self.jsonServer.jsonrpc_dumpprivkey, 'bogus')
      
      # verify that the root private key is not found
      self.assertRaises(PrivateKeyNotFound, self.jsonServer.jsonrpc_dumpprivkey, addr58)
      
      # verify that the first private key can be found
      firstHash160 = self.wallet.getNextUnusedAddress().getAddr160()
      firstAddr58 = hash160_to_addrStr(firstHash160)
      actualPrivateKey = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58)
      expectedPrivateKey = self.wallet.getAddrByHash160(firstHash160).serializePlainPrivateKey()
      self.assertEqual(actualPrivateKey, expectedPrivateKey)
      
      # Verify that a locked wallet Raises WalletUnlockNeeded Exception
      kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
      self.wallet.changeKdfParams(*kdfParams)
      self.wallet.changeWalletEncryption( securePassphrase=self.passphrase )
      self.wallet.lock()
      self.assertRaises(WalletUnlockNeeded, self.jsonServer.jsonrpc_dumpprivkey, addr58)

   def testEncryptwallet(self):
      kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
      self.wallet.changeKdfParams(*kdfParams)
      self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
      self.assertTrue(self.wallet.isLocked)
      
      # Verify that a locked wallet Raises WalletUnlockNeeded Exception
      self.assertRaises(WalletUnlockNeeded, self.jsonServer.jsonrpc_encryptwallet, PASSPHRASE1)
      
   def testUnlockwallet(self):
      kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1)
      self.wallet.changeKdfParams(*kdfParams)
      self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
      self.assertTrue(self.wallet.isLocked)
      self.jsonServer.jsonrpc_unlockwallet(PASSPHRASE1, UNLOCK_TIMEOUT)
      self.assertFalse(self.wallet.isLocked)
      time.sleep(UNLOCK_TIMEOUT+1)
      self.wallet.checkWalletLockTimeout()
      self.assertTrue(self.wallet.isLocked)
      
   def testGetWalletInfo(self):
      wltInfo = self.jsonServer.jsonrpc_getwalletinfo()
      self.assertEqual(wltInfo['name'], TEST_WALLET_NAME)
      self.assertEqual(wltInfo['description'], TEST_WALLET_DESCRIPTION)
      self.assertEqual(wltInfo['balance'], AmountToJSON(self.wallet.getBalance('Spend')))
      self.assertEqual(wltInfo['keypoolsize'], self.wallet.addrPoolSize)
      self.assertEqual(wltInfo['numaddrgen'], len(self.wallet.addrMap))
      self.assertEqual(wltInfo['highestusedindex'], self.wallet.highestUsedChainIndex)
   
   # This should always return 0 balance
   # Need to create our own test net to test with balances
   def testGetBalance(self):
      for ballanceType in ['spendable','spend', 'unconf', \
                           'unconfirmed', 'total', 'ultimate','unspent', 'full']:
         self.assertEqual(self.jsonServer.jsonrpc_getbalance(ballanceType),
                          AmountToJSON(self.wallet.getBalance(ballanceType)))
      self.assertEqual(self.jsonServer.jsonrpc_getbalance('bogus'), -1)