Exemplo n.º 1
0
 public void timeLockedTransaction(boolean useNotFound) throws Exception {
   connectWithVersion(useNotFound ? 70001 : 60001);
   // Test that if we receive a relevant transaction that has a lock time, it doesn't result in a
   // notification
   // until we explicitly opt in to seeing those.
   ECKey key = new ECKey();
   Wallet wallet = new Wallet(unitTestParams);
   wallet.addKey(key);
   peer.addWallet(wallet);
   final Transaction[] vtx = new Transaction[1];
   wallet.addEventListener(
       new AbstractWalletEventListener() {
         @Override
         public void onCoinsReceived(
             Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
           vtx[0] = tx;
         }
       });
   // Send a normal relevant transaction, it's received correctly.
   Transaction t1 = TestUtils.createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), key);
   inbound(writeTarget, t1);
   GetDataMessage getdata = (GetDataMessage) outbound(writeTarget);
   if (useNotFound) {
     inbound(writeTarget, new NotFoundMessage(unitTestParams, getdata.getItems()));
   } else {
     bouncePing();
   }
   pingAndWait(writeTarget);
   Threading.waitForUserCode();
   assertNotNull(vtx[0]);
   vtx[0] = null;
   // Send a timelocked transaction, nothing happens.
   Transaction t2 = TestUtils.createFakeTx(unitTestParams, Utils.toNanoCoins(2, 0), key);
   t2.setLockTime(999999);
   inbound(writeTarget, t2);
   Threading.waitForUserCode();
   assertNull(vtx[0]);
   // Now we want to hear about them. Send another, we are told about it.
   wallet.setAcceptRiskyTransactions(true);
   inbound(writeTarget, t2);
   getdata = (GetDataMessage) outbound(writeTarget);
   if (useNotFound) {
     inbound(writeTarget, new NotFoundMessage(unitTestParams, getdata.getItems()));
   } else {
     bouncePing();
   }
   pingAndWait(writeTarget);
   Threading.waitForUserCode();
   assertEquals(t2, vtx[0]);
 }
Exemplo n.º 2
0
 private void checkTimeLockedDependency(boolean shouldAccept, boolean useNotFound)
     throws Exception {
   // Initial setup.
   connectWithVersion(useNotFound ? 70001 : 60001);
   ECKey key = new ECKey();
   Wallet wallet = new Wallet(unitTestParams);
   wallet.addKey(key);
   wallet.setAcceptRiskyTransactions(shouldAccept);
   peer.addWallet(wallet);
   final Transaction[] vtx = new Transaction[1];
   wallet.addEventListener(
       new AbstractWalletEventListener() {
         @Override
         public void onCoinsReceived(
             Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
           vtx[0] = tx;
         }
       });
   // t1 -> t2 [locked] -> t3 (not available)
   Transaction t2 = new Transaction(unitTestParams);
   t2.setLockTime(999999);
   // Add a fake input to t3 that goes nowhere.
   Sha256Hash t3 = Sha256Hash.create("abc".getBytes(Charset.forName("UTF-8")));
   t2.addInput(
       new TransactionInput(
           unitTestParams, t2, new byte[] {}, new TransactionOutPoint(unitTestParams, 0, t3)));
   t2.getInput(0).setSequenceNumber(0xDEADBEEF);
   t2.addOutput(Utils.toNanoCoins(1, 0), new ECKey());
   Transaction t1 = new Transaction(unitTestParams);
   t1.addInput(t2.getOutput(0));
   t1.addOutput(Utils.toNanoCoins(1, 0), key); // Make it relevant.
   // Announce t1.
   InventoryMessage inv = new InventoryMessage(unitTestParams);
   inv.addTransaction(t1);
   inbound(writeTarget, inv);
   // Send it.
   GetDataMessage getdata = (GetDataMessage) outbound(writeTarget);
   assertEquals(t1.getHash(), getdata.getItems().get(0).hash);
   inbound(writeTarget, t1);
   // Nothing arrived at our event listener yet.
   assertNull(vtx[0]);
   // We request t2.
   getdata = (GetDataMessage) outbound(writeTarget);
   assertEquals(t2.getHash(), getdata.getItems().get(0).hash);
   inbound(writeTarget, t2);
   if (!useNotFound) bouncePing();
   // We request t3.
   getdata = (GetDataMessage) outbound(writeTarget);
   assertEquals(t3, getdata.getItems().get(0).hash);
   // Can't find it: bottom of tree.
   if (useNotFound) {
     NotFoundMessage notFound = new NotFoundMessage(unitTestParams);
     notFound.addItem(new InventoryItem(InventoryItem.Type.Transaction, t3));
     inbound(writeTarget, notFound);
   } else {
     bouncePing();
   }
   pingAndWait(writeTarget);
   Threading.waitForUserCode();
   // We're done but still not notified because it was timelocked.
   if (shouldAccept) assertNotNull(vtx[0]);
   else assertNull(vtx[0]);
 }
  @Test
  public void testAppearedAtChainHeightDepthAndWorkDone() throws Exception {
    // Test the TransactionConfidence appearedAtChainHeight, depth and workDone field are stored.

    BlockChain chain = new BlockChain(params, myWallet, new MemoryBlockStore(params));

    final ArrayList<Transaction> txns = new ArrayList<Transaction>(2);
    myWallet.addEventListener(
        new AbstractWalletEventListener() {
          @Override
          public void onCoinsReceived(
              Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
            txns.add(tx);
          }
        });

    // Start by building two blocks on top of the genesis block.
    Block b1 = params.getGenesisBlock().createNextBlock(myAddress);
    BigInteger work1 = b1.getWork();
    assertTrue(work1.signum() > 0);

    Block b2 = b1.createNextBlock(myAddress);
    BigInteger work2 = b2.getWork();
    assertTrue(work2.signum() > 0);

    assertTrue(chain.add(b1));
    assertTrue(chain.add(b2));

    // We now have the following chain:
    //     genesis -> b1 -> b2

    // Check the transaction confidence levels are correct before wallet roundtrip.
    Threading.waitForUserCode();
    assertEquals(2, txns.size());

    TransactionConfidence confidence0 = txns.get(0).getConfidence();
    TransactionConfidence confidence1 = txns.get(1).getConfidence();

    assertEquals(1, confidence0.getAppearedAtChainHeight());
    assertEquals(2, confidence1.getAppearedAtChainHeight());

    assertEquals(2, confidence0.getDepthInBlocks());
    assertEquals(1, confidence1.getDepthInBlocks());

    // Roundtrip the wallet and check it has stored the depth and workDone.
    Wallet rebornWallet = roundTrip(myWallet);

    Set<Transaction> rebornTxns = rebornWallet.getTransactions(false);
    assertEquals(2, rebornTxns.size());

    // The transactions are not guaranteed to be in the same order so sort them to be in chain
    // height order if required.
    Iterator<Transaction> it = rebornTxns.iterator();
    Transaction txA = it.next();
    Transaction txB = it.next();

    Transaction rebornTx0, rebornTx1;
    if (txA.getConfidence().getAppearedAtChainHeight() == 1) {
      rebornTx0 = txA;
      rebornTx1 = txB;
    } else {
      rebornTx0 = txB;
      rebornTx1 = txA;
    }

    TransactionConfidence rebornConfidence0 = rebornTx0.getConfidence();
    TransactionConfidence rebornConfidence1 = rebornTx1.getConfidence();

    assertEquals(1, rebornConfidence0.getAppearedAtChainHeight());
    assertEquals(2, rebornConfidence1.getAppearedAtChainHeight());

    assertEquals(2, rebornConfidence0.getDepthInBlocks());
    assertEquals(1, rebornConfidence1.getDepthInBlocks());
  }