Android Open Source - bitcoin-wallet Block Chain






From Project

Back to project page bitcoin-wallet.

License

The source code is released under:

Copyright (C) 2011 by Caleb Anderson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the ...

If you think the Android project bitcoin-wallet listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package net.dirtyfilthy.bitcoin.core;
// www  . j a va  2 s. co m
import java.util.HashMap;
import java.util.Vector;
import java.math.BigInteger;

import net.dirtyfilthy.bitcoin.protocol.ProtocolVersion;
import net.dirtyfilthy.bitcoin.util.BigIntegerTools;
import net.dirtyfilthy.bitcoin.util.MyHex;
public class BlockChain {
  private HashMap<BigInteger,Vector<Block>> orphanBlocks=new HashMap<BigInteger,Vector<Block>>();
  private BlockStore blockStore;
  int medianTimespan=ProtocolVersion.medianTimeSpan();
  long[] medianValues=new long[medianTimespan];
  
  public BlockChain(){
    blockStore=new BlockStore();
  }
  
  
  public Block topBlock(){
    return blockStore.top();
  }
  
  public void setBlockStore(BlockStore blockStore) {
    this.blockStore = blockStore;
  }

  public BlockStore getBlockStore() {
    return blockStore;
  }

  public boolean isKnown(Block block){
    return blockStore.has(block);
  }
  
  
  
  
  public synchronized Block addBlock(Block block) throws InvalidBlockException, OrphanBlockException, BlockExistsException{
    if(!block.validProofOfWork()){
      System.out.println("FAILED PROOF OF WORK");
      System.out.println("bits   :"+Integer.toHexString((int) block.getBits()));
      System.out.println("bits %d:"+block.getBits());
      System.out.println("hash   :"+MyHex.encodePadded(block.hash(), 32));
      System.out.println("target :"+MyHex.encodePadded(block.targetHash().toByteArray(), 32));
      System.out.println("height :"+blockStore.top().getHeight());
      throw new InvalidBlockException("Invalid proof of work");
    }
    BigInteger prevHash=block.previousBigIntegerHash();
    Block prev=blockStore.getPrevious(block);
    if(prev==null){
      if(orphanBlocks.containsKey(prevHash)){
        orphanBlocks.get(prevHash).add(block);
      }
      else{
        Vector<Block> vb=new Vector<Block>();
        orphanBlocks.put(prevHash,vb);
        vb.add(block);
      }
      throw new OrphanBlockException("Can't find previous block hash");
    }
    if(block.getBits()!=nextDifficulty(prev)){
      System.out.println("INVALID DIFFICULTY WORK");
      System.out.println("bits   :"+Integer.toHexString((int) block.getBits()));
      System.out.println("next   :"+Integer.toHexString((int) nextDifficulty(prev)));
      System.out.println("bits %d:"+block.getBits());
      System.out.println("hash   :"+MyHex.encodePadded(block.hash(), 32));
      System.out.println("target :"+MyHex.encodePadded(block.targetHash().toByteArray(), 32));
      System.out.println("height :"+blockStore.top().getHeight());
      throw new InvalidBlockException("Invalid difficulty");
    }
    if(block.getTime()<=getMedianTimePast(prev)){
      System.out.println("height :"+blockStore.top().getHeight());
      System.out.println("time :"+block.getTimestamp());
      throw new InvalidBlockException("Incorrect timestamp");
    }
    
  
  
    
    Block lastTop=blockStore.top();
    blockStore.put(block);
    Block top=blockStore.top();
    if(lastTop!=top && lastTop!=prev){
        // reorganize
    }
    
    if(orphanBlocks.containsKey(block.bigIntegerHash())){
      Vector<Block> toAdd=orphanBlocks.remove(block.bigIntegerHash());
      for(Block b : toAdd){
        
        // don't catch OrphanBlockExceptions here, they should never occur
        
        try{
          this.addBlock(b);
        }
        catch(InvalidBlockException e){
          // ignore
          continue;
        }
      }
    }
    if(block.getHeight() % 100 == 0){
      System.out.println("New height "+blockStore.top().getHeight());
    }
    return block;
  }
  
  
  public long nextDifficulty(Block b){
     long targetTimespan = ProtocolVersion.targetTimespan(); // two weeks
     long targetSpacing = ProtocolVersion.targetInterval();
     long interval = targetTimespan / targetSpacing;
     if(blockStore.getPrevious(b)==null){
       return BigIntegerTools.compactBigInt(ProtocolVersion.proofOfWorkLimit());
     }
     if((b.getHeight()+1) % interval != 0){
       return b.getBits();
     }
    
     Block first=b;
     Block prev;
     for (int i = 0; i<interval-1; i++){
       prev=blockStore.getPrevious(first);
       if(prev==null){
         break;
       }
       first=prev;
     }
     long actualTimespan=(b.getTime()-first.getTime())/1000;
     if (actualTimespan < targetTimespan/4){
       actualTimespan = targetTimespan/4;
     }
     if (actualTimespan > targetTimespan*4){
       actualTimespan = targetTimespan*4;
     }
     BigInteger nextDifficulty=b.targetHash().multiply(BigInteger.valueOf(actualTimespan));
     nextDifficulty=nextDifficulty.divide(BigInteger.valueOf(targetTimespan));
     if(nextDifficulty.compareTo(ProtocolVersion.proofOfWorkLimit())>0){
       nextDifficulty=ProtocolVersion.proofOfWorkLimit();
     }
     return BigIntegerTools.compactBigInt(nextDifficulty);
  }
  
  public long getMedianTimePast(Block b){
    long temp;
    long time;
    int timespan=medianTimespan;
    Block current=b;
    int j;
    // insertion sort this motherfucker
    
    for(int i=0;i<timespan;i++){
      time=current.getTime();
      
      medianValues[i]=time;
      
      for (j = i; j > 0; j--) {
              if (medianValues[j-1] > medianValues[j]) {
                 temp = medianValues[j];
                 medianValues[j] = medianValues[j-1];
                 medianValues[j-1] = temp;
              }
           }
      current=blockStore.getPrevious(current);
      if(current==null){
        timespan=i+1;
        break;
      }
    }
    
    return medianValues[timespan/2];
  }


  
}




Java Source Code List

net.dirtyfilthy.bitcoin.core.Address.java
net.dirtyfilthy.bitcoin.core.Base58Hash160.java
net.dirtyfilthy.bitcoin.core.BlockChain.java
net.dirtyfilthy.bitcoin.core.BlockExistsException.java
net.dirtyfilthy.bitcoin.core.BlockStore.java
net.dirtyfilthy.bitcoin.core.Block.java
net.dirtyfilthy.bitcoin.core.BtcValue.java
net.dirtyfilthy.bitcoin.core.ByteArrayable.java
net.dirtyfilthy.bitcoin.core.InvalidBlockException.java
net.dirtyfilthy.bitcoin.core.OpCode.java
net.dirtyfilthy.bitcoin.core.OpData.java
net.dirtyfilthy.bitcoin.core.OrphanBlockException.java
net.dirtyfilthy.bitcoin.core.Script.java
net.dirtyfilthy.bitcoin.core.TxIn.java
net.dirtyfilthy.bitcoin.core.TxOut.java
net.dirtyfilthy.bitcoin.core.Tx.java
net.dirtyfilthy.bitcoin.protocol.AddressBook.java
net.dirtyfilthy.bitcoin.protocol.AddressPacket.java
net.dirtyfilthy.bitcoin.protocol.BlockPacket.java
net.dirtyfilthy.bitcoin.protocol.ConnectionHandler.java
net.dirtyfilthy.bitcoin.protocol.Connection.java
net.dirtyfilthy.bitcoin.protocol.GetAddressPacket.java
net.dirtyfilthy.bitcoin.protocol.GetBlocksPacket.java
net.dirtyfilthy.bitcoin.protocol.GetDataPacket.java
net.dirtyfilthy.bitcoin.protocol.GetHeadersPacket.java
net.dirtyfilthy.bitcoin.protocol.HeadersPacket.java
net.dirtyfilthy.bitcoin.protocol.InventoryPacket.java
net.dirtyfilthy.bitcoin.protocol.InventoryVector.java
net.dirtyfilthy.bitcoin.protocol.IrcBootStrap.java
net.dirtyfilthy.bitcoin.protocol.MalformedPacketException.java
net.dirtyfilthy.bitcoin.protocol.PacketFactory.java
net.dirtyfilthy.bitcoin.protocol.PacketType.java
net.dirtyfilthy.bitcoin.protocol.Packet.java
net.dirtyfilthy.bitcoin.protocol.PingPacket.java
net.dirtyfilthy.bitcoin.protocol.ProtocolVersion.java
net.dirtyfilthy.bitcoin.protocol.ReplyPacket.java
net.dirtyfilthy.bitcoin.protocol.TxPacket.java
net.dirtyfilthy.bitcoin.protocol.VersionAckPacket.java
net.dirtyfilthy.bitcoin.protocol.VersionPacket.java
net.dirtyfilthy.bitcoin.util.Base58.java
net.dirtyfilthy.bitcoin.util.BigIntegerTools.java
net.dirtyfilthy.bitcoin.util.HashTools.java
net.dirtyfilthy.bitcoin.util.KeyTools.java
net.dirtyfilthy.bitcoin.util.MyHex.java
net.dirtyfilthy.bitcoin.wallet.ExposedSQLiteCursor.java
net.dirtyfilthy.bitcoin.wallet.InvalidPasswordException.java
net.dirtyfilthy.bitcoin.wallet.KeyRing.java
net.dirtyfilthy.bitcoin.wallet.SqlBlockStore.java
net.dirtyfilthy.bitcoin.wallet.Wallet.java