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)))
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)
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)))
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)