@Test public void earliestKeyTime() throws Exception { long now = Utils.currentTimeSeconds(); // mock long yesterday = now - 86400; assertEquals(now, group.getEarliestKeyCreationTime()); Utils.rollMockClock(10000); group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); Utils.rollMockClock(10000); group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); // Check that all keys are assumed to be created at the same instant the seed is. assertEquals(now, group.getEarliestKeyCreationTime()); ECKey key = new ECKey(); key.setCreationTimeSeconds(yesterday); group.importKeys(key); assertEquals(yesterday, group.getEarliestKeyCreationTime()); }
/** * Loads wallet data from the given protocol buffer and inserts it into the given Wallet object. * This is primarily useful when you wish to pre-register extension objects. Note that if loading * fails the provided Wallet object may be in an indeterminate state and should be thrown away. * * @throws IOException if there is a problem reading the stream. * @throws IllegalArgumentException if the wallet is corrupt. */ public void readWallet(Protos.Wallet walletProto, Wallet wallet) throws IOException { // TODO: This method should throw more specific exception types than IllegalArgumentException. // Read the scrypt parameters that specify how encryption and decryption is performed. if (walletProto.hasEncryptionParameters()) { Protos.ScryptParameters encryptionParameters = walletProto.getEncryptionParameters(); wallet.setKeyCrypter(new KeyCrypterScrypt(encryptionParameters)); } if (walletProto.hasDescription()) { wallet.setDescription(walletProto.getDescription()); } // Read all keys for (Protos.Key keyProto : walletProto.getKeyList()) { if (!(keyProto.getType() == Protos.Key.Type.ORIGINAL || keyProto.getType() == Protos.Key.Type.ENCRYPTED_SCRYPT_AES)) { throw new IllegalArgumentException( "Unknown key type in wallet, type = " + keyProto.getType()); } byte[] privKey = keyProto.hasPrivateKey() ? keyProto.getPrivateKey().toByteArray() : null; EncryptedPrivateKey encryptedPrivateKey = null; if (keyProto.hasEncryptedPrivateKey()) { Protos.EncryptedPrivateKey encryptedPrivateKeyProto = keyProto.getEncryptedPrivateKey(); encryptedPrivateKey = new EncryptedPrivateKey( encryptedPrivateKeyProto.getInitialisationVector().toByteArray(), encryptedPrivateKeyProto.getEncryptedPrivateKey().toByteArray()); } byte[] pubKey = keyProto.hasPublicKey() ? keyProto.getPublicKey().toByteArray() : null; ECKey ecKey; final KeyCrypter keyCrypter = wallet.getKeyCrypter(); if (keyCrypter != null && keyCrypter.getUnderstoodEncryptionType() != EncryptionType.UNENCRYPTED) { // If the key is encrypted construct an ECKey using the encrypted private key bytes. ecKey = new ECKey(encryptedPrivateKey, pubKey, keyCrypter); } else { // Construct an unencrypted private key. ecKey = new ECKey(privKey, pubKey); } ecKey.setCreationTimeSeconds((keyProto.getCreationTimestamp() + 500) / 1000); wallet.addKey(ecKey); } // Read all transactions and insert into the txMap. for (Protos.Transaction txProto : walletProto.getTransactionList()) { readTransaction(txProto, wallet.getParams()); } // Update transaction outputs to point to inputs that spend them for (Protos.Transaction txProto : walletProto.getTransactionList()) { WalletTransaction wtx = connectTransactionOutputs(txProto); wallet.addWalletTransaction(wtx); } // Update the lastBlockSeenHash. if (!walletProto.hasLastSeenBlockHash()) { wallet.setLastBlockSeenHash(null); } else { wallet.setLastBlockSeenHash(byteStringToHash(walletProto.getLastSeenBlockHash())); } if (!walletProto.hasLastSeenBlockHeight()) { wallet.setLastBlockSeenHeight(-1); } else { wallet.setLastBlockSeenHeight(walletProto.getLastSeenBlockHeight()); } loadExtensions(wallet, walletProto); if (walletProto.hasVersion()) { wallet.setVersion(walletProto.getVersion()); } // Make sure the object can be re-used to read another wallet without corruption. txMap.clear(); }
@Test public void testReplayManagerSyncSingleWallet() throws Exception { // Get the system property runFunctionalTest to see if the functional // tests need running. String runFunctionalTests = System.getProperty(Constants.RUN_FUNCTIONAL_TESTS_PARAMETER); if (Boolean.TRUE.toString().equalsIgnoreCase(runFunctionalTests)) { // Date format is UTC with century, T time separator and Z for UTC // timezone. formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); // Initialise replay manager ReplayManager replayManager = ReplayManager.INSTANCE; assertNotNull(replayManager); replayManager.initialise(controller, true); String replayWalletPath = multiBitDirectory.getAbsolutePath() + File.separator + "replay.wallet"; // Create a new wallet. Wallet replayWallet = new Wallet(NetworkParameters.prodNet()); // Add in the replay key. DumpedPrivateKey replayDumpedPrivateKey = new DumpedPrivateKey(NetworkParameters.prodNet(), REPLAY1_PRIVATE_KEY); ECKey replayKey = replayDumpedPrivateKey.getKey(); replayKey.setCreationTimeSeconds(formatter.parse(START_OF_REPLAY_PERIOD).getTime() / 1000); log.debug("replayPrivateKey getCreationTimeSeconds = " + replayKey.getCreationTimeSeconds()); replayWallet.addKey(replayKey); WalletData perWalletModelData = new WalletData(); perWalletModelData.setWalletInfo( new WalletInfoData(replayWalletPath, replayWallet, MultiBitWalletVersion.PROTOBUF)); perWalletModelData.setWallet(replayWallet); perWalletModelData.setWalletFilename(replayWalletPath); perWalletModelData.setWalletDescription("testReplayManagerSyncSingleWallet test"); controller.getModel().getPerWalletModelDataList().add(perWalletModelData); log.debug("Replay wallet before replay = \n" + replayWallet.toString()); assertEquals(BALANCE_AT_START, replayWallet.getBalance()); log.debug("Replaying blockchain"); // Create a ReplayTask to replay the replay wallet from the // START_OF_REPLAY_PERIOD. List<WalletData> perWalletModelDataList = new ArrayList<WalletData>(); perWalletModelDataList.add(perWalletModelData); ReplayTask replayTask = new ReplayTask( perWalletModelDataList, formatter.parse(START_OF_REPLAY_PERIOD), ReplayTask.UNKNOWN_START_HEIGHT); replayManager.offerReplayTask(replayTask); // Run for a while. log.debug("Twiddling thumbs for 60 seconds ..."); Thread.sleep(60000); log.debug("... 60 seconds later."); // Check the wallet - there should be some transactions in there. if (replayWallet.getTransactions(true).size() > 0) { // We are done. } else { // Run for a while longer. log.debug("Twiddling thumbs for another 60 seconds ..."); Thread.sleep(60000); log.debug("... 60 seconds later."); if (replayWallet.getTransactions(true).size() > 0) { // We are done. } else { if (simpleViewSystem.getNumberOfBlocksDownloaded() > 0) { // Well it tried but probably got a slow connection - // give it a pass. } else { fail("No blocks were downloaded on replay"); } } } // Print out replay wallet after replay. log.debug("Replay wallet after replay = \n" + replayWallet); } else { log.debug( "Not running functional test: ReplayManagerTest#testReplayManagerSyncSingleWallet. Add '-DrunFunctionalTests=true' to run"); } }