Ejemplo n.º 1
0
  public void putInternal(Transaction tx, Sha256Hash block_hash, StatusContext ctx) {

    if (block_hash == null) {
      ctx.setStatus("TX_SERIALIZE");
      SerializedTransaction s_tx = new SerializedTransaction(tx);
      ctx.setStatus("TX_PUT");
      // System.out.println("Transaction " + tx.getHash() + " " + Util.measureSerialization(s_tx));
      file_db.getTransactionMap().put(tx.getHash(), s_tx);
    }

    // putTxOutSpents(tx);
    boolean confirmed = (block_hash != null);

    ctx.setStatus("TX_GET_ADDR");
    Collection<String> addrs = getAllAddresses(tx, confirmed);

    Random rnd = new Random();

    ctx.setStatus("TX_SAVE_ADDRESS");
    file_db.addAddressesToTxMap(addrs, tx.getHash());

    imported_transactions.incrementAndGet();
    int h = -1;
    if (block_hash != null) {
      ctx.setStatus("TX_GET_HEIGHT");
      h = block_store.getHeight(block_hash);
    }

    ctx.setStatus("TX_NOTIFY");
    jelly.getElectrumNotifier().notifyNewTransaction(tx, addrs, h);
    ctx.setStatus("TX_DONE");
  }
Ejemplo n.º 2
0
  private void waitForBlockStored(Sha256Hash hash) {
    if (hash.toString().equals("0000000000000000000000000000000000000000000000000000000000000000"))
      return;

    try {
      if (file_db.getBlockMap().containsKey(hash)) return;
    } finally {

    }

    Semaphore block_wait_sem = null;
    synchronized (in_progress) {
      block_wait_sem = in_progress.get(hash);
      if (block_wait_sem == null) {
        block_wait_sem = new Semaphore(0);
        in_progress.put(hash, block_wait_sem);
      }
    }

    try {
      // System.out.println("Waiting for " + hash);
      block_wait_sem.acquire(1);

    } catch (java.lang.InterruptedException e) {
      throw new RuntimeException(e);
    }
  }
Ejemplo n.º 3
0
  public void checkConsistency() throws com.google.bitcoin.store.BlockStoreException {
    StoredBlock head = block_store.getChainHead();

    StoredBlock curr_block = head;

    Sha256Hash genisis_hash = params.getGenesisBlock().getHash();
    int checked = 0;

    while (true) {
      Sha256Hash curr_hash = curr_block.getHeader().getHash();

      if (curr_block.getHeight() % 10000 == 0) {
        System.out.println("Block: " + curr_block.getHeight());
      }
      if (!file_db.getBlockMap().containsKey(curr_hash)) {
        throw new RuntimeException("Missing block: " + curr_hash);
      }
      checked++;
      // if (checked > 20) return;

      if (curr_hash.equals(genisis_hash)) return;

      curr_block = curr_block.getPrev(block_store);
    }
  }
Ejemplo n.º 4
0
  public Transaction getTransaction(Sha256Hash hash) {
    Transaction tx = null;
    synchronized (transaction_cache) {
      tx = transaction_cache.get(hash);
    }
    if (tx == null) {

      SerializedTransaction s_tx = file_db.getTransactionMap().get(hash);

      if (s_tx != null) {
        tx = s_tx.getTx(params);
        synchronized (transaction_cache) {
          transaction_cache.put(hash, SerializedTransaction.scrubTransaction(params, tx));
        }
      }
    }
    return tx;
  }
Ejemplo n.º 5
0
  private void putInternal(Block block, StatusContext ctx) {
    long t1 = System.currentTimeMillis();
    Sha256Hash hash = block.getHash();

    ctx.setStatus("BLOCK_CHECK_EXIST");
    if (file_db.getBlockMap().containsKey(hash)) {
      imported_blocks.incrementAndGet();
      return;
    }
    // Mark block as in progress

    Semaphore block_wait_sem;
    synchronized (in_progress) {
      block_wait_sem = in_progress.get(hash);
      if (block_wait_sem == null) {
        block_wait_sem = new Semaphore(0);
        in_progress.put(hash, block_wait_sem);
      }
    }

    // Kick off threaded storage of transactions
    int size = 0;

    ctx.setStatus("BLOCK_TX_CACHE_INSERT");
    synchronized (transaction_cache) {
      for (Transaction tx : block.getTransactions()) {
        transaction_cache.put(tx.getHash(), SerializedTransaction.scrubTransaction(params, tx));
      }
    }

    ctx.setStatus("BLOCK_TX_ENQUE");
    LinkedList<Sha256Hash> tx_list = new LinkedList<Sha256Hash>();

    Collection<Map.Entry<String, Sha256Hash>> addrTxLst =
        new LinkedList<Map.Entry<String, Sha256Hash>>();
    Map<Sha256Hash, SerializedTransaction> txs_map =
        new HashMap<Sha256Hash, SerializedTransaction>();

    for (Transaction tx : block.getTransactions()) {
      imported_transactions.incrementAndGet();
      Collection<String> addrs = getAllAddresses(tx, true);

      for (String addr : addrs) {
        addrTxLst.add(
            new java.util.AbstractMap.SimpleEntry<String, Sha256Hash>(addr, tx.getHash()));
      }

      txs_map.put(tx.getHash(), new SerializedTransaction(tx));

      tx_list.add(tx.getHash());
      size++;
    }

    ctx.setStatus("TX_SAVEALL");
    file_db.getTransactionMap().putAll(txs_map);

    ctx.setStatus("BLOCK_TX_MAP_ADD");
    file_db.addTxsToBlockMap(tx_list, hash);

    ctx.setStatus("ADDR_SAVEALL");
    file_db.addAddressesToTxMap(addrTxLst);

    int h = block_store.getHeight(hash);

    for (Transaction tx : block.getTransactions()) {
      Collection<String> addrs = getAllAddresses(tx, true);
      ctx.setStatus("TX_NOTIFY");
      jelly.getElectrumNotifier().notifyNewTransaction(tx, addrs, h);
      ctx.setStatus("TX_DONE");
    }

    // Once all transactions are in, check for prev block in this store

    ctx.setStatus("BLOCK_WAIT_PREV");
    Sha256Hash prev_hash = block.getPrevBlockHash();

    waitForBlockStored(prev_hash);

    // System.out.println("Block " + hash + " " + Util.measureSerialization(new
    // SerializedBlock(block)));

    ctx.setStatus("BLOCK_SAVE");
    file_db.getBlockMap().put(hash, new SerializedBlock(block));

    block_wait_sem.release(1024);
    boolean wait_for_utxo = false;
    if (jelly.isUpToDate() && jelly.getUtxoTrieMgr().isUpToDate()) {
      wait_for_utxo = true;
    }

    jelly.getUtxoTrieMgr().notifyBlock(wait_for_utxo);
    if (wait_for_utxo) {
      jelly.getEventLog().alarm("UTXO root hash: " + jelly.getUtxoTrieMgr().getRootHash());
    }
    jelly.getElectrumNotifier().notifyNewBlock(block);

    long t2 = System.currentTimeMillis();
    DecimalFormat df = new DecimalFormat("0.000");
    double sec = (t2 - t1) / 1000.0;

    if (h % block_print_every == 0) {
      jelly
          .getEventLog()
          .alarm(
              "Saved block: "
                  + hash
                  + " - "
                  + h
                  + " - "
                  + size
                  + " ("
                  + df.format(sec)
                  + " seconds)");
    }
    jelly
        .getEventLog()
        .log(
            "Saved block: "
                + hash
                + " - "
                + h
                + " - "
                + size
                + " ("
                + df.format(sec)
                + " seconds)");

    imported_blocks.incrementAndGet();
  }