Ejemplo n.º 1
0
  @Test
  public void disconnectOldVersions1() throws Exception {
    // Set up the connection with an old version.
    final SettableFuture<Void> connectedFuture = SettableFuture.create();
    final SettableFuture<Void> disconnectedFuture = SettableFuture.create();
    peer.addEventListener(
        new AbstractPeerEventListener() {
          @Override
          public void onPeerConnected(Peer peer, int peerCount) {
            connectedFuture.set(null);
          }

          @Override
          public void onPeerDisconnected(Peer peer, int peerCount) {
            disconnectedFuture.set(null);
          }
        });
    connectWithVersion(500);
    // We must wait uninterruptibly here because connect[WithVersion] generates a peer that
    // interrupts the current
    // thread when it disconnects.
    Uninterruptibles.getUninterruptibly(connectedFuture);
    Uninterruptibles.getUninterruptibly(disconnectedFuture);
    try {
      peer.writeTarget.writeBytes(new byte[1]);
      fail();
    } catch (IOException e) {
      assertTrue(
          (e.getCause() != null && e.getCause() instanceof CancelledKeyException)
              || (e instanceof SocketException && e.getMessage().equals("Socket is closed")));
    }
  }
Ejemplo n.º 2
0
  // Check that it starts downloading the block chain correctly on request.
  @Test
  public void startBlockChainDownload() throws Exception {
    Block b1 = createFakeBlock(blockStore).block;
    blockChain.add(b1);
    Block b2 = makeSolvedTestBlock(b1);
    blockChain.add(b2);

    connect();
    fail.set(true);
    peer.addEventListener(
        new AbstractPeerEventListener() {
          @Override
          public void onChainDownloadStarted(Peer p, int blocksLeft) {
            if (p == peer && blocksLeft == 108) fail.set(false);
          }
        },
        Threading.SAME_THREAD);
    peer.startBlockChainDownload();

    List<Sha256Hash> expectedLocator = new ArrayList<Sha256Hash>();
    expectedLocator.add(b2.getHash());
    expectedLocator.add(b1.getHash());
    expectedLocator.add(unitTestParams.getGenesisBlock().getHash());

    GetBlocksMessage message = (GetBlocksMessage) outbound(writeTarget);
    assertEquals(message.getLocator(), expectedLocator);
    assertEquals(Sha256Hash.ZERO_HASH, message.getStopHash());
  }
Ejemplo n.º 3
0
 @Test
 public void testAddEventListener() throws Exception {
   connect();
   PeerEventListener listener = new AbstractPeerEventListener();
   peer.addEventListener(listener);
   assertTrue(peer.removeEventListener(listener));
   assertFalse(peer.removeEventListener(listener));
 }
Ejemplo n.º 4
0
  // Check that inventory message containing blocks we want is processed correctly.
  @Test
  public void newBlock() throws Exception {
    Block b1 = createFakeBlock(blockStore).block;
    blockChain.add(b1);
    final Block b2 = makeSolvedTestBlock(b1);
    // Receive notification of a new block.
    final InventoryMessage inv = new InventoryMessage(unitTestParams);
    InventoryItem item = new InventoryItem(InventoryItem.Type.Block, b2.getHash());
    inv.addItem(item);

    final AtomicInteger newBlockMessagesReceived = new AtomicInteger(0);

    connect();
    // Round-trip a ping so that we never see the response verack if we attach too quick
    pingAndWait(writeTarget);
    peer.addEventListener(
        new AbstractPeerEventListener() {
          @Override
          public synchronized Message onPreMessageReceived(Peer p, Message m) {
            if (p != peer) fail.set(true);
            if (m instanceof Pong) return m;
            int newValue = newBlockMessagesReceived.incrementAndGet();
            if (newValue == 1 && !inv.equals(m)) fail.set(true);
            else if (newValue == 2 && !b2.equals(m)) fail.set(true);
            else if (newValue > 3) fail.set(true);
            return m;
          }

          @Override
          public synchronized void onBlocksDownloaded(Peer p, Block block, int blocksLeft) {
            int newValue = newBlockMessagesReceived.incrementAndGet();
            if (newValue != 3
                || p != peer
                || !block.equals(b2)
                || blocksLeft != OTHER_PEER_CHAIN_HEIGHT - 2) fail.set(true);
          }
        },
        Threading.SAME_THREAD);
    long height = peer.getBestHeight();

    inbound(writeTarget, inv);
    pingAndWait(writeTarget);
    assertEquals(height + 1, peer.getBestHeight());
    // Response to the getdata message.
    inbound(writeTarget, b2);

    pingAndWait(writeTarget);
    Threading.waitForUserCode();
    pingAndWait(writeTarget);
    assertEquals(3, newBlockMessagesReceived.get());

    GetDataMessage getdata = (GetDataMessage) outbound(writeTarget);
    List<InventoryItem> items = getdata.getItems();
    assertEquals(1, items.size());
    assertEquals(b2.getHash(), items.get(0).hash);
    assertEquals(InventoryItem.Type.Block, items.get(0).type);
  }
Ejemplo n.º 5
0
  public void recursiveDownload(boolean useNotFound) throws Exception {
    // Using ping or notfound?
    connectWithVersion(useNotFound ? 70001 : 60001);
    // Check that we can download all dependencies of an unconfirmed relevant transaction from the
    // mempool.
    ECKey to = new ECKey();

    final Transaction[] onTx = new Transaction[1];
    peer.addEventListener(
        new AbstractPeerEventListener() {
          @Override
          public void onTransaction(Peer peer1, Transaction t) {
            onTx[0] = t;
          }
        },
        Threading.SAME_THREAD);

    // Make the some fake transactions in the following graph:
    //   t1 -> t2 -> [t5]
    //      -> t3 -> t4 -> [t6]
    //      -> [t7]
    //      -> [t8]
    // The ones in brackets are assumed to be in the chain and are represented only by hashes.
    Transaction t2 = TestUtils.createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), to);
    Sha256Hash t5 = t2.getInput(0).getOutpoint().getHash();
    Transaction t4 = TestUtils.createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), new ECKey());
    Sha256Hash t6 = t4.getInput(0).getOutpoint().getHash();
    t4.addOutput(Utils.toNanoCoins(1, 0), new ECKey());
    Transaction t3 = new Transaction(unitTestParams);
    t3.addInput(t4.getOutput(0));
    t3.addOutput(Utils.toNanoCoins(1, 0), new ECKey());
    Transaction t1 = new Transaction(unitTestParams);
    t1.addInput(t2.getOutput(0));
    t1.addInput(t3.getOutput(0));
    Sha256Hash someHash =
        new Sha256Hash("2b801dd82f01d17bbde881687bf72bc62e2faa8ab8133d36fcb8c3abe7459da6");
    t1.addInput(
        new TransactionInput(
            unitTestParams,
            t1,
            new byte[] {},
            new TransactionOutPoint(unitTestParams, 0, someHash)));
    Sha256Hash anotherHash =
        new Sha256Hash("3b801dd82f01d17bbde881687bf72bc62e2faa8ab8133d36fcb8c3abe7459da6");
    t1.addInput(
        new TransactionInput(
            unitTestParams,
            t1,
            new byte[] {},
            new TransactionOutPoint(unitTestParams, 1, anotherHash)));
    t1.addOutput(Utils.toNanoCoins(1, 0), to);
    t1 = TestUtils.roundTripTransaction(unitTestParams, t1);
    t2 = TestUtils.roundTripTransaction(unitTestParams, t2);
    t3 = TestUtils.roundTripTransaction(unitTestParams, t3);
    t4 = TestUtils.roundTripTransaction(unitTestParams, t4);

    // Announce the first one. Wait for it to be downloaded.
    InventoryMessage inv = new InventoryMessage(unitTestParams);
    inv.addTransaction(t1);
    inbound(writeTarget, inv);
    GetDataMessage getdata = (GetDataMessage) outbound(writeTarget);
    Threading.waitForUserCode();
    assertEquals(t1.getHash(), getdata.getItems().get(0).hash);
    inbound(writeTarget, t1);
    pingAndWait(writeTarget);
    assertEquals(t1, onTx[0]);
    // We want its dependencies so ask for them.
    ListenableFuture<List<Transaction>> futures = peer.downloadDependencies(t1);
    assertFalse(futures.isDone());
    // It will recursively ask for the dependencies of t1: t2, t3, someHash and anotherHash.
    getdata = (GetDataMessage) outbound(writeTarget);
    assertEquals(4, getdata.getItems().size());
    assertEquals(t2.getHash(), getdata.getItems().get(0).hash);
    assertEquals(t3.getHash(), getdata.getItems().get(1).hash);
    assertEquals(someHash, getdata.getItems().get(2).hash);
    assertEquals(anotherHash, getdata.getItems().get(3).hash);
    long nonce = -1;
    if (!useNotFound) nonce = ((Ping) outbound(writeTarget)).getNonce();
    // For some random reason, t4 is delivered at this point before it's needed - perhaps it was a
    // Bloom filter
    // false positive. We do this to check that the mempool is being checked for seen transactions
    // before
    // requesting them.
    inbound(writeTarget, t4);
    // Deliver the requested transactions.
    inbound(writeTarget, t2);
    inbound(writeTarget, t3);
    if (useNotFound) {
      NotFoundMessage notFound = new NotFoundMessage(unitTestParams);
      notFound.addItem(new InventoryItem(InventoryItem.Type.Transaction, someHash));
      notFound.addItem(new InventoryItem(InventoryItem.Type.Transaction, anotherHash));
      inbound(writeTarget, notFound);
    } else {
      inbound(writeTarget, new Pong(nonce));
    }
    assertFalse(futures.isDone());
    // It will recursively ask for the dependencies of t2: t5 and t4, but not t3 because it already
    // found t4.
    getdata = (GetDataMessage) outbound(writeTarget);
    assertEquals(getdata.getItems().get(0).hash, t2.getInput(0).getOutpoint().getHash());
    // t5 isn't found and t4 is.
    if (useNotFound) {
      NotFoundMessage notFound = new NotFoundMessage(unitTestParams);
      notFound.addItem(new InventoryItem(InventoryItem.Type.Transaction, t5));
      inbound(writeTarget, notFound);
    } else {
      bouncePing();
    }
    assertFalse(futures.isDone());
    // Continue to explore the t4 branch and ask for t6, which is in the chain.
    getdata = (GetDataMessage) outbound(writeTarget);
    assertEquals(t6, getdata.getItems().get(0).hash);
    if (useNotFound) {
      NotFoundMessage notFound = new NotFoundMessage(unitTestParams);
      notFound.addItem(new InventoryItem(InventoryItem.Type.Transaction, t6));
      inbound(writeTarget, notFound);
    } else {
      bouncePing();
    }
    pingAndWait(writeTarget);
    // That's it, we explored the entire tree.
    assertTrue(futures.isDone());
    List<Transaction> results = futures.get();
    assertTrue(results.contains(t2));
    assertTrue(results.contains(t3));
    assertTrue(results.contains(t4));
  }