KeyChainGroup implements KeyBag { public Address freshAddress(KeyChain.KeyPurpose purpose) { DeterministicKeyChain chain = getActiveKeyChain(); if (chain.isMarried()) { Script outputScript = chain.freshOutputScript(purpose); checkState(outputScript.isPayToScriptHash()); Address freshAddress = Address.fromP2SHScript(params, outputScript); maybeLookaheadScripts(); currentAddresses.put(purpose, freshAddress); return freshAddress; } else { return freshKey(purpose).toAddress(params); } } KeyChainGroup(NetworkParameters params);  KeyChainGroup(NetworkParameters params, DeterministicSeed seed);  KeyChainGroup(NetworkParameters params, DeterministicSeed seed, ImmutableList<ChildNumber> accountPath);  KeyChainGroup(NetworkParameters params, DeterministicKey watchKey); private  KeyChainGroup(NetworkParameters params, @Nullable BasicKeyChain basicKeyChain, List<DeterministicKeyChain> chains,
                          @Nullable EnumMap<KeyChain.KeyPurpose, DeterministicKey> currentKeys, @Nullable KeyCrypter crypter); void createAndActivateNewHDChain(); void addAndActivateHDChain(DeterministicKeyChain chain); DeterministicKey currentKey(KeyChain.KeyPurpose purpose); Address currentAddress(KeyChain.KeyPurpose purpose); DeterministicKey freshKey(KeyChain.KeyPurpose purpose); List<DeterministicKey> freshKeys(KeyChain.KeyPurpose purpose, int numberOfKeys); Address freshAddress(KeyChain.KeyPurpose purpose); final DeterministicKeyChain getActiveKeyChain(); void setLookaheadSize(int lookaheadSize); int getLookaheadSize(); void setLookaheadThreshold(int num); int getLookaheadThreshold(); int importKeys(List<ECKey> keys); int importKeys(ECKey... keys); boolean checkPassword(CharSequence password); boolean checkAESKey(KeyParameter aesKey); int importKeysAndEncrypt(final List<ECKey> keys, KeyParameter aesKey); @Override @Nullable RedeemData findRedeemDataFromScriptHash(byte[] scriptHash); void markP2SHAddressAsUsed(Address address); @Nullable @Override ECKey findKeyFromPubHash(byte[] pubkeyHash); void markPubKeyHashAsUsed(byte[] pubkeyHash); boolean hasKey(ECKey key); @Nullable @Override ECKey findKeyFromPubKey(byte[] pubkey); void markPubKeyAsUsed(byte[] pubkey); int numKeys(); boolean removeImportedKey(ECKey key); final boolean isMarried(); void encrypt(KeyCrypter keyCrypter, KeyParameter aesKey); void decrypt(KeyParameter aesKey); boolean isEncrypted(); boolean isWatching(); @Nullable KeyCrypter getKeyCrypter(); List<ECKey> getImportedKeys(); long getEarliestKeyCreationTime(); int getBloomFilterElementCount(); BloomFilter getBloomFilter(int size, double falsePositiveRate, long nTweak); boolean isRequiringUpdateAllBloomFilter(); void addEventListener(KeyChainEventListener listener); void addEventListener(KeyChainEventListener listener, Executor executor); boolean removeEventListener(KeyChainEventListener listener); List<Protos.Key> serializeToProtobuf(); static KeyChainGroup fromProtobufUnencrypted(NetworkParameters params, List<Protos.Key> keys, KeyChainFactory factory); static KeyChainGroup fromProtobufEncrypted(NetworkParameters params, List<Protos.Key> keys, KeyCrypter crypter, KeyChainFactory factory); DeterministicKeyChain upgradeToDeterministic(long keyRotationTimeSecs, @Nullable KeyParameter aesKey); boolean isDeterministicUpgradeRequired(); String toString(boolean includePrivateKeys); List<DeterministicKeyChain> getDeterministicKeyChains(); int getCombinedKeyLookaheadEpochs();  }
@Test public void freshAddress() throws Exception { group = createMarriedKeyChainGroup(); Address a1 = group.freshAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS); Address a2 = group.freshAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS); assertTrue(a1.isP2SHAddress()); assertNotEquals(a1, a2); group.getBloomFilterElementCount(); assertEquals(((group.getLookaheadSize() + group.getLookaheadThreshold()) * 2) + (2 - group.getLookaheadThreshold()) + group.getActiveKeyChain().getAccountPath().size() + 3 , group.numKeys()); Address a3 = group.currentAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS); assertEquals(a2, a3); }