Getting balance/downloading blockhain with bitcoinj I am playing around with bitoinj and I can't seem to even get the most basic functionality running.

What I want to do: I have one wallet with one address. I want to dowload blockchain and from that, get the wallet balance.

What I did is following code (in scala, but it is more or less the same thing as Java), the wallet is in address.walet, I want the blockain to be saved at saved.blockchain:

val params = NetworkParameters.prodNet
val walletFile = new java.io.File("address.wallet");
val wallet = Wallet.loadFromFile(walletFile)

val key = wallet.keychain.get(0)
val address:String = key.toAddress(params).toString
println("ADDRESS IS : "+address)

val blockStore = new BoundedOverheadBlockStore(params, new java.io.File("saved.blockchain"))
val chain = new BlockChain(params, wallet, blockStore)
val peerGroup = new PeerGroup(params, chain)
peerGroup.setUserAgent("BitToy", "0.1")

peerGroup.addPeerDiscovery(new DnsDiscovery(params))
peerGroup.addWallet(wallet)
println("START DOWNLOADING BLOCKCHAIN")

peerGroup.start()
peerGroup.downloadBlockChain()
peerGroup.stop()
println("DONE; BALANCE IS :")
println(wallet.getBalance)


I do have balance on the address in the wallet.

Now, when I run it for the first time, the blockchain (or, rather, the headers) gets downloaded and I see the correct balance. However, when I run it for second time, I just see:

ADDRESS IS : [correct address here]
Aug 19, 2012 8:06:00 AM com.google.bitcoin.store.BoundedOverheadBlockStore load
INFO: Reading block store from saved.blockchain
Aug 19, 2012 8:06:00 AM com.google.bitcoin.store.BoundedOverheadBlockStore load
INFO: Read chain head from disk: 00000000000001b10c347b5ec05f9a1910d541905c5cd8827784a5c3e0695c95
Aug 19, 2012 8:06:00 AM com.google.bitcoin.core.BlockChain &lt;init&gt;
INFO: chain head is at height 194575:
v1 block: 
   previous block: 00000000000005ac50dc06021362cd4c284fafd4a1bdb7bad2849c978a875bb1
   merkle root: 158aedd0bc3386c7686f85ab933fd9e3ecb38e348b121ed0e61e2e776eda04a1
   time: [1345356028] Sun Aug 19 08:00:28 CEST 2012
   difficulty target (nBits): 436709470
   nonce: 4238997601

START DOWNLOADING BLOCKCHAIN
Aug 19, 2012 8:06:31 AM com.google.bitcoin.discovery.DnsDiscovery getPeers
INFO: DNS lookup for dnsseed.bitcoin.dashjr.org failed.
Aug 19, 2012 8:06:36 AM com.google.bitcoin.core.TCPNetworkConnection$NetworkHandler channelConnected
INFO: Announcing ourselves as: /BitCoinJ:0.6-SNAPSHOT/BitMessage:0.1/
Aug 19, 2012 8:06:41 AM com.google.bitcoin.core.Peer$PeerHandler exceptionCaught
INFO: com.google.bitcoin.core.Peer$PeerHandler@193f6e2 - No route to host
Aug 19, 2012 8:06:46 AM com.google.bitcoin.core.Peer$PeerHandler exceptionCaught
INFO: com.google.bitcoin.core.Peer$PeerHandler@61736e - No route to host
Aug 19, 2012 8:06:52 AM com.google.bitcoin.core.TCPNetworkConnection$NetworkHandler channelConnected
INFO: Announcing ourselves as: /BitCoinJ:0.6-SNAPSHOT/BitMessage:0.1/
Aug 19, 2012 8:06:52 AM com.google.bitcoin.core.PeerGroup handleNewPeer
INFO: Peer(seed.bitcoin.sipa.be/50.130.4.89:8333): New peer
Aug 19, 2012 8:06:52 AM com.google.bitcoin.core.PeerGroup handleNewPeer
INFO:   starting block chain download
Aug 19, 2012 8:06:52 AM com.google.bitcoin.core.PeerGroup setDownloadPeer
INFO: Setting download peer: Peer(seed.bitcoin.sipa.be/50.130.4.89:8333)
Downloading block chain of size 0. 
Done downloading block chain
Aug 19, 2012 8:06:52 AM com.google.bitcoin.core.Peer blockChainDownload
INFO: Peer(seed.bitcoin.sipa.be/50.130.4.89:8333): blockChainDownload(0000000000000000000000000000000000000000000000000000000000000000) current head = 00000000000001b10c347b5ec05f9a1910d541905c5cd8827784a5c3e0695c95
DONE; BALANCE IS :
0
Aug 19, 2012 8:06:52 AM com.google.bitcoin.core.PeerGroup$PeerGroupThread run
INFO: shutdown start


and the balance is zero. If I delete the saved blockchain and let it re-download again, it works again, but only for one time.

What am I doing wrong?
OK, now I get it.

I can't.

Bitcoinj saves only the headers. And - what I did not know - you can't get the balance with just headers. 

For more ingormation you can see the exact description what is in the headers here https://en.bitcoin.it/wiki/Block_hashing_algorithm

What I can do, however, is saving the wallet right afterwards. Which I will do.



previous "answer"/thinking out loud:

I am poking around in source code.

It seems like the important part is when sendTransactionsToWallet is called in BlockChain.java - but it gets only called during connectBlock and nothing else.

connectBlock is called only during add. And the only added blocks are the new blocks from the network, not the ones from BlockStore.

But I will look around the code a bit more.



I am not sure, what terrible would happen, if I rewrote the constructor of BlockChain.java from:

/**
 * Constructs a BlockChain connected to the given list of wallets and a store.
 */
public BlockChain(NetworkParameters params, List&lt;Wallet&gt; wallets,
                  BlockStore blockStore) throws BlockStoreException {
    this.blockStore = blockStore;
    chainHead = blockStore.getChainHead();
    log.info("chain head is at height {}:\n{}", chainHead.getHeight(), chainHead.getHeader());
    this.params = params;
    this.wallets = new ArrayList&lt;Wallet&gt;(wallets);
}


to (writing from my head, getters/setters might not be right, etc)

/**
 * Constructs a BlockChain connected to the given list of wallets and a store.
 */
public BlockChain(NetworkParameters params, List&lt;Wallet&gt; wallets,
                  BlockStore blockStore) throws BlockStoreException {
    this.blockStore = blockStore;
    chainHead = blockStore.getChainHead();
    log.info("chain head is at height {}:\n{}", chainHead.getHeight(), chainHead.getHeader());
    this.params = params;
    this.wallets = new ArrayList&lt;Wallet&gt;(wallets);
    StoredBlock sBlock = blockStore.getChainHead();
    Sha256Hash prevHash = sBlock.header.prevBlockHash();
    while (prevHash!=Sha256Hash.ZERO_HASH) {
        for (Wallet wallet:wallets){
            sendTransactionsToWallet(sBlock, NewBlockType.SIDE_CHAIN, wallet, sBlock.transactions); 
        }
        sBlock = blockStore.get(hash);
        prevHash = sBlock.header.prevBlockHash();
    }
}


but again, I don't want to reinvent the wheel or anything.