@Test
 public void bloom() throws Exception {
   ECKey key1 = group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
   ECKey key2 = new ECKey();
   BloomFilter filter =
       group.getBloomFilter(
           group.getBloomFilterElementCount(), 0.001, (long) (Math.random() * Long.MAX_VALUE));
   assertTrue(filter.contains(key1.getPubKeyHash()));
   assertTrue(filter.contains(key1.getPubKey()));
   assertFalse(filter.contains(key2.getPubKey()));
   // Check that the filter contains the lookahead buffer and threshold zone.
   for (int i = 0; i < LOOKAHEAD_SIZE + group.getLookaheadThreshold(); i++) {
     ECKey k = group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
     assertTrue(filter.contains(k.getPubKeyHash()));
   }
   // We ran ahead of the lookahead buffer.
   assertFalse(filter.contains(group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS).getPubKey()));
   group.importKeys(key2);
   filter =
       group.getBloomFilter(
           group.getBloomFilterElementCount(), 0.001, (long) (Math.random() * Long.MAX_VALUE));
   assertTrue(filter.contains(key1.getPubKeyHash()));
   assertTrue(filter.contains(key1.getPubKey()));
   assertTrue(filter.contains(key2.getPubKey()));
 }
 protected void pingAndWait(final InboundMessageQueuer p) throws Exception {
   final long nonce = (long) (Math.random() * Long.MAX_VALUE);
   // Start with an inbound Pong as pingAndWait often happens immediately after an inbound() call,
   // and then wants
   // to wait on an outbound message, so we do it in the same order or we see race conditions
   inboundPongAndWait(p, nonce);
   outboundPingAndWait(p, nonce);
 }
 /**
  * Returns the number of seconds from now until this servers next channel will expire, or zero if
  * no unexpired channels found.
  */
 public long getSecondsUntilExpiry(Sha256Hash id) {
   lock.lock();
   try {
     final Set<StoredClientChannel> setChannels = mapChannels.get(id);
     final long nowSeconds = Utils.currentTimeSeconds();
     int earliestTime = Integer.MAX_VALUE;
     for (StoredClientChannel channel : setChannels) {
       synchronized (channel) {
         if (channel.expiryTimeSeconds() > nowSeconds)
           earliestTime = Math.min(earliestTime, (int) channel.expiryTimeSeconds());
       }
     }
     return earliestTime == Integer.MAX_VALUE ? 0 : earliestTime - nowSeconds;
   } finally {
     lock.unlock();
   }
 }
  @Test
  public void bloomFilterForMarriedChains() throws Exception {
    group = createMarriedKeyChainGroup();
    int bufferSize = group.getLookaheadSize() + group.getLookaheadThreshold();
    int expected = bufferSize * 2 /* chains */ * 2 /* elements */;
    assertEquals(expected, group.getBloomFilterElementCount());
    Address address1 = group.freshAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS);
    assertEquals(expected, group.getBloomFilterElementCount());
    BloomFilter filter =
        group.getBloomFilter(expected + 2, 0.001, (long) (Math.random() * Long.MAX_VALUE));
    assertTrue(filter.contains(address1.getHash160()));

    Address address2 = group.freshAddress(KeyChain.KeyPurpose.CHANGE);
    assertTrue(filter.contains(address2.getHash160()));

    // Check that the filter contains the lookahead buffer.
    for (int i = 0; i < bufferSize - 1 /* issued address */; i++) {
      Address address = group.freshAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS);
      assertTrue("key " + i, filter.contains(address.getHash160()));
    }
    // We ran ahead of the lookahead buffer.
    assertFalse(
        filter.contains(group.freshAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS).getHash160()));
  }