Example #1
0
 @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();
  }
Example #3
0
  @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");
    }
  }