bitcoin/BRWallet.c
// wallets are composed of chains of addresses
// each chain is traversed until a gap of a number of addresses is found that haven't been used in any transactions
// this function writes to addrs an array of <gapLimit> unused addresses following the last used address in the chain
// the internal chain is used for change addresses and the external chain for receive addresses
// addrs may be NULL to only generate addresses for BRWalletContainsAddress()
// returns the number addresses written to addrs
wallets are composed of chains of addresses
each chain is traversed until a gap of a number of addresses is found that haven't been used in any transactions
this function writes to addrs an array of  unused addresses following the last used address in the chain
the internal chain is used for change addresses and the external chain for receive addresses
addrs may be NULL to only generate addresses for BRWalletContainsAddress()
returns the number addresses written to addrs
wallets are composed of chains of addresses each chain is traversed until a gap of a number of addresses is found that haven ' t been used in any transactions this function writes to addrs an array of unused addresses following the last used address in the chain the internal chain is used for change addresses and the external chain for receive addresses addrs may be NULL to only generate addresses for BRWalletContainsAddress () returns the number addresses written to addrs
size_t BRWalletUnusedAddrs(BRWallet *wallet, BRAddress addrs[], uint32_t gapLimit, uint32_t internal)
{
    UInt160 *chain = NULL, *origChain;
    size_t i, j = 0, count, startCount;
    assert(wallet != NULL);
    assert(gapLimit > 0);
    pthread_mutex_lock(&wallet->lock);
    if (internal == SEQUENCE_EXTERNAL_CHAIN) chain = wallet->externalChain;
    if (internal == SEQUENCE_INTERNAL_CHAIN) chain = wallet->internalChain;
    assert(chain != NULL);
    origChain = chain;
    i = count = startCount = array_count(chain);
    while (i > 0 && ! BRSetContains(wallet->usedPKH, &chain[i - 1])) i--;
    while (i + gapLimit > count) { 
        BRKey key;
        uint8_t pubKey[BRBIP32PubKey(NULL, 0, wallet->masterPubKey, internal, count)];
        size_t len = BRBIP32PubKey(pubKey, sizeof(pubKey), wallet->masterPubKey, internal, (uint32_t)count);
        if (! BRKeySetPubKey(&key, pubKey, len)) break;
        array_add(chain, BRKeyHash160(&key));
        count++;
        if (BRSetContains(wallet->usedPKH, &chain[array_count(chain) - 1])) i = count;
    }
    if (addrs && i + gapLimit <= count) {
        for (j = 0; j < gapLimit; j++) {
            BRAddressFromHash160(addrs[j].s, sizeof(*addrs), wallet->addrParams, &chain[i + j]);
        }
    }
    if (chain == origChain) {
        for (i = startCount; i < count; i++) {
            BRSetAdd(wallet->allPKH, &chain[i]);
        }
    }
    else {
        if (internal == SEQUENCE_EXTERNAL_CHAIN) wallet->externalChain = chain;
        if (internal == SEQUENCE_INTERNAL_CHAIN) wallet->internalChain = chain;
        BRSetClear(wallet->allPKH); 
        for (i = array_count(wallet->internalChain); i > 0; i--) {
            BRSetAdd(wallet->allPKH, &wallet->internalChain[i - 1]);
        }
        for (i = array_count(wallet->externalChain); i > 0; i--) {
            BRSetAdd(wallet->allPKH, &wallet->externalChain[i - 1]);
        }
    }
    pthread_mutex_unlock(&wallet->lock);
    return j;
}
size_t BRWalletUnusedAddrs ( BRWallet * wallet , BRAddress addrs [ ] , uint32_t gapLimit , uint32_t internal ) { UInt160 * chain = NULL , * origChain ; size_t i , j = 0 , count , startCount ; assert ( wallet != NULL ) ; assert ( gapLimit > 0 ) ; pthread_mutex_lock ( & wallet -> lock ) ; if ( internal == SEQUENCE_EXTERNAL_CHAIN ) chain = wallet -> externalChain ; if ( internal == SEQUENCE_INTERNAL_CHAIN ) chain = wallet -> internalChain ; assert ( chain != NULL ) ; origChain = chain ; i = count = startCount = array_count ( chain ) ; while ( i > 0 && ! BRSetContains ( wallet -> usedPKH , & chain [ i - 1 ] ) ) i -- ; while ( i + gapLimit > count ) { BRKey key ; uint8_t pubKey [ BRBIP32PubKey ( NULL , 0 , wallet -> masterPubKey , internal , count ) ] ; size_t len = BRBIP32PubKey ( pubKey , sizeof ( pubKey ) , wallet -> masterPubKey , internal , ( uint32_t ) count ) ; if ( ! BRKeySetPubKey ( & key , pubKey , len ) ) break ; array_add ( chain , BRKeyHash160 ( & key ) ) ; count ++ ; if ( BRSetContains ( wallet -> usedPKH , & chain [ array_count ( chain ) - 1 ] ) ) i = count ; } if ( addrs && i + gapLimit <= count ) { for ( j = 0 ; j < gapLimit ; j ++ ) { BRAddressFromHash160 ( addrs [ j ] . s , sizeof ( * addrs ) , wallet -> addrParams , & chain [ i + j ] ) ; } } if ( chain == origChain ) { for ( i = startCount ; i < count ; i ++ ) { BRSetAdd ( wallet -> allPKH , & chain [ i ] ) ; } } else { if ( internal == SEQUENCE_EXTERNAL_CHAIN ) wallet -> externalChain = chain ; if ( internal == SEQUENCE_INTERNAL_CHAIN ) wallet -> internalChain = chain ; BRSetClear ( wallet -> allPKH ) ; for ( i = array_count ( wallet -> internalChain ) ; i > 0 ; i -- ) { BRSetAdd ( wallet -> allPKH , & wallet -> internalChain [ i - 1 ] ) ; } for ( i = array_count ( wallet -> externalChain ) ; i > 0 ; i -- ) { BRSetAdd ( wallet -> allPKH , & wallet -> externalChain [ i - 1 ] ) ; } } pthread_mutex_unlock ( & wallet -> lock ) ; return j ; }
wallets are composed of chains of addresses
each chain is traversed until a gap of a number of addresses is found that haven't been used in any transactions
this function writes to addrs an array of <gapLimit> unused addresses following the last used address in the chain
the internal chain is used for change addresses and the external chain for receive addresses
addrs may be NULL to only generate addresses for BRWalletContainsAddress()
returns the number addresses written to addrs
wallets are composed of chains of addresses each chain is traversed until a gap of a number of addresses is found that haven ' t been used in any transactions this function writes to addrs an array of <gapLimit > unused addresses following the last used address in the chain the internal chain is used for change addresses and the external chain for receive addresses addrs may be NULL to only generate addresses for BRWalletContainsAddress () returns the number addresses written to addrs
// keep only the trailing contiguous block of addresses with no transactions // generate new addresses up to gapLimit // was chain moved to a new memory location? // clear and rebuild allAddrs