<commit_before>/**
 * chain.js - blockchain management for bcoin
 * Copyright (c) 2014-2015, <NAME> (MIT License)
 * https://github.com/indutny/bcoin
 */

var inherits = require('inherits');
var EventEmitter = require('events').EventEmitter;

var bcoin = require('../bcoin');
var bn = require('bn.js');
var constants = bcoin.protocol.constants;
var network = bcoin.protocol.network;
var utils = bcoin.utils;
var assert = utils.assert;
var fs = bcoin.fs;

/**
 * Chain
 */

function Chain(options) {
  if (!(this instanceof Chain))
    return new Chain(options);

  EventEmitter.call(this);

  if (!options)
    options = {};

  this.options = options;

  if (this.options.debug)
    bcoin.debug = this.options.debug;

  this.db = new bcoin.chaindb(this);
  this.heightLookup = {};
  this.request = new utils.RequestCache();
  this.loading = false;
  this.tip = null;

  this.orphan = {
    map: {},
    bmap: {},
    count: 0,
    size: 0
  };

  this._saveEntry(bcoin.chainblock.fromJSON(this, {
    hash: network.genesis.hash,
    version: network.genesis.version,
    prevBlock: network.genesis.prevBlock,
    merkleRoot: network.genesis.merkleRoot,
    ts: network.genesis.ts,
    bits: network.genesis.bits,
    nonce: network.genesis.nonce,
    height: 0
  }), true);

  Chain.global = this;

  this._init();
}

inherits(Chain, EventEmitter);

Chain.codes = {
  okay: 0,
  newOrphan: 1,
  knownOrphan: 2,
  forked: 3,
  invalid: 4,
  badCheckpoint: 4,
  unchanged: 5
};

Chain.messages = {
  0: 'Block was added successfully',
  1: 'Block is a new orphan',
  2: 'Block is a known orphan',
  3: 'Block is a greater fork',
  4: 'Block verification failed',
  5: 'Block does not match checkpoint',
  6: 'Chain is unchanged'
};

Chain.msg = function msg(code) {
  return Chain.messages[code] || 'Unknown';
};

Chain.prototype._init = function _init() {
  var self = this;

  this.loading = true;

  utils.debug('Chain is loading.');

  utils.nextTick(function() {
    var count = self.db.count();
    var entry;
    var i = 1;

    function done() {
      self.loading = false;
      self.emit('load');

      utils.debug('Chain successfully loaded.');
    }

    (function next() {
      if (i >= count)
        return done();
      self.db.getAsync(i, function(err, entry) {
        if (err)
          throw err;
        self._saveEntry(entry);
        i += 1;
        next();
      });
    })();
  });
};

Chain.prototype._addEntry = function _addEntry(entry) {
  var self = this;
  var existing;

  // Already added
  if (this.heightLookup[entry.hash] != null) {
    assert(this.heightLookup[entry.hash] === entry.height);
    return Chain.codes.unchanged;
  }

  // Duplicate height
  existing = this.db.get(entry.height);
  if (existing && existing.hash === entry.hash)
    return Chain.codes.unchanged;
<commit_msg>add some data integrity checks when loading the chain.<commit_after>/**
 * chain.js - blockchain management for bcoin
 * Copyright (c) 2014-2015, <NAME> (MIT License)
 * https://github.com/indutny/bcoin
 */

var inherits = require('inherits');
var EventEmitter = require('events').EventEmitter;

var bcoin = require('../bcoin');
var bn = require('bn.js');
var constants = bcoin.protocol.constants;
var network = bcoin.protocol.network;
var utils = bcoin.utils;
var assert = utils.assert;
var fs = bcoin.fs;

/**
 * Chain
 */

function Chain(options) {
  if (!(this instanceof Chain))
    return new Chain(options);

  EventEmitter.call(this);

  if (!options)
    options = {};

  this.options = options;

  if (this.options.debug)
    bcoin.debug = this.options.debug;

  this.db = new bcoin.chaindb(this);
  this.heightLookup = {};
  this.request = new utils.RequestCache();
  this.loading = false;
  this.tip = null;

  this.orphan = {
    map: {},
    bmap: {},
    count: 0,
    size: 0
  };

  this._saveEntry(bcoin.chainblock.fromJSON(this, {
    hash: network.genesis.hash,
    version: network.genesis.version,
    prevBlock: network.genesis.prevBlock,
    merkleRoot: network.genesis.merkleRoot,
    ts: network.genesis.ts,
    bits: network.genesis.bits,
    nonce: network.genesis.nonce,
    height: 0
  }), true);

  Chain.global = this;

  this._init();
}

inherits(Chain, EventEmitter);

Chain.codes = {
  okay: 0,
  newOrphan: 1,
  knownOrphan: 2,
  forked: 3,
  invalid: 4,
  badCheckpoint: 4,
  unchanged: 5
};

Chain.messages = {
  0: 'Block was added successfully',
  1: 'Block is a new orphan',
  2: 'Block is a known orphan',
  3: 'Block is a greater fork',
  4: 'Block verification failed',
  5: 'Block does not match checkpoint',
  6: 'Chain is unchanged'
};

Chain.msg = function msg(code) {
  return Chain.messages[code] || 'Unknown';
};

Chain.prototype._init = function _init() {
  var self = this;

  this.loading = true;

  utils.debug('Chain is loading.');

  utils.nextTick(function() {
    var count = self.db.count();
    var lastEntry;
    var i = 1;

    function done(height) {
      if (height != null) {
        utils.debug(
          'Blockchain is corrupt after height %d. Resetting.',
          height);
        self.resetHeight(height);
      } else {
        utils.debug('Chain successfully loaded.');
      }
      self.loading = false;
      self.emit('load');
    }

    (function next() {
      if (i >= count)
        return done();

      self.db.getAsync(i, function(err, entry) {
        if (err)
          throw err;

        // Do some paranoid checks.
        if (lastEntry && entry.prevBlock !== lastEntry.hash)
          return done(Math.max(0, i - 2));

        self._saveEntry(entry);
        lastEntry = entry;
        i += 1;
        next();
      });
    })();
  });
};

Chain.prototype._addEntry = function _addEntry(entry) {
  var self = this;
  var existing;

  // Already added
  if (this.heightLookup[entry.hash] != null) {
    assert(this.heightLookup[entry.hash] === entry.height);
    return Chain.codes.unchanged;
  }

  // Duplicate height
  existing = this.db.get(entry.height);
  if (existing && existing.hash === entry.hash)
    return Chain.codes.unchanged;

{'fraction_non_alphanumeric': 0.14707824364476724, 'fraction_numerical': 0.00924397490921096, 'mean_word_length': 2.837238758708043, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7615195', 'n_tokens_mistral': 2065, 'n_tokens_neox': 1987, 'n_words': 502}