<commit_before>/**
 * NOTES
 * block details are child block hash, parent block hash, isUncle, isProcessed, and total difficulty
 * block details are stored to key  'detail'+<blockhash>
 * meta.rawHead is the the head of the chain with the most POW
 * meta.head is the head of the chain that has had its state root verifed
 */
const async = require('async')
const Block = require('ethereumjs-block')
const utils = require('ethereumjs-util')
const BN = utils.BN
const Ethash = require('ethashjs')
const rlp = utils.rlp

var Blockchain = module.exports = function (db, validate) {
  this.db = db
  this.ethash = new Ethash(db)
  this.validate = validate === undefined ? true : validate
  this._initDone = false
  this._pendingSaves = []
  this._pendingGets = []
  this._init()
}

/**
 * Fetches the meta info about the blockchain from the db. Meta info contains
 * the hash of the head block and the hash of the genisis block
 * @method _init
 */
Blockchain.prototype._init = function () {
  var self = this

  function onHeadFound () {
    // run the pending save operations
    async.whilst(function () {
      return self._pendingSaves.length
    }, function (cb) {
      var op = self._pendingSaves.pop()
      self._addBlock(op[0], function () {
        op[1]()
        cb()
      })
    }, function () {
      delete self._pendingSaves
      self._initDone = true

      // run the pending getHead
      self._pendingGets.forEach(function (args) {
        self.getHead.apply(self, args)
      })
    })
  }

  this.db.get('meta', {
    valueEncoding: 'json'
  },
    function (err, meta) {
      if (!err && meta) {
        self.meta = meta
        self.meta.td = new BN(self.meta.td)
      } else {
        self.meta = {
          heads: {},
          td: new BN()
        }
        self._generateGenesis()
      }
      onHeadFound()
    })
}

Blockchain.prototype._generateGenesis = function () {
  var genesisBlock = new Block()
  genesisBlock.setGenesisParams()
  this.putBlock(genesisBlock, function () {})
}

/**
 * Returns that head block
 * @method getHead
 * @param cb Function the callback
 */
Blockchain.prototype.getHead = function (name, cb) {
  if (typeof name === 'function') {
    cb = name
    name = 'vm'
  }

  if (!this._initDone) {
    this._pendingGets.push(arguments)
  } else {
    // if the head is not found return the rawHead
    var hash = this.meta.heads[name] || this.meta.rawHead
    this.getBlock(hash, cb)
  }
}

/**
 * Adds a block to the blockchain
 * @method addBlock
 * @param {object} block -the block to be added to the block chain
 * @param {function} cb - a callback function
 */
Blockchain.prototype.putBlock = function (block, cb) {
  if (!this._initDone) {
    this._pendingSaves.push([block, cb])
  } else {
    this._addBlock(block, cb)
  }
}

Blockchain.prototype.putBlocks = function (blocks, cb) {
  var self = this
  async.eachSeries(blocks, function (block, done) {
    self.putBlock(block, done)
  }, cb)
}

Blockchain.prototype._addBlock = function (block, cb) {
  var self = this
  var blockHash = block.hash().toString('hex')
  var parentDetails
  var dbOps = []

  if (block.constructor !== Block) {
    block = new Block(block)
  }

  async.series([

    function verify (cb2) {
      if (!self.validate) {
        return cb2()
      }

      block.validate(self, cb2)
    },
    function verifyPOW (cb2) {
      if (!self.validate) {
        return cb2()
      }

      self.ethash.verifyPOW(block, function (valid) {
        if (valid) {
          cb2()
        } else {
          cb2('invalid POW')
        }
      })
    },
    // look up the parent meta info
    function parentInfo (cb2) {
      // if genesis block
      if (block.isGenesis()) {
        return cb2()<commit_msg>one and only genesis block<commit_after>/**
 * NOTES
 * block details are child block hash, parent block hash, isUncle, isProcessed, and total difficulty
 * block details are stored to key  'detail'+<blockhash>
 * meta.rawHead is the the head of the chain with the most POW
 * meta.head is the head of the chain that has had its state root verifed
 */
const async = require('async')
const Block = require('ethereumjs-block')
const utils = require('ethereumjs-util')
const BN = utils.BN
const Ethash = require('ethashjs')
const rlp = utils.rlp

var Blockchain = module.exports = function (db, validate) {
  this.db = db
  this.ethash = new Ethash(db)
  this.validate = validate === undefined ? true : validate
  this._initDone = false
  this._pendingSaves = []
  this._pendingGets = []
  this._init()
}

/**
 * Fetches the meta info about the blockchain from the db. Meta info contains
 * the hash of the head block and the hash of the genisis block
 * @method _init
 */
Blockchain.prototype._init = function () {
  var self = this

  function onHeadFound () {
    // run the pending save operations
    async.whilst(function () {
      return self._pendingSaves.length
    }, function (cb) {
      var op = self._pendingSaves.pop()
      self._addBlock(op[0], function () {
        op[1]()
        cb()
      })
    }, function () {
      delete self._pendingSaves
      self._initDone = true

      // run the pending getHead
      self._pendingGets.forEach(function (args) {
        self.getHead.apply(self, args)
      })
    })
  }

  this.db.get('meta', {
    valueEncoding: 'json'
  },
    function (err, meta) {
      if (!err && meta) {
        self.meta = meta
        self.meta.td = new BN(self.meta.td)
      } else {
        self.meta = {
          heads: {},
          td: new BN()
        }
      }
      onHeadFound()
    })
}

Blockchain.prototype.setCanicalGenesisBlock = function (cb) {
  var genesisBlock = new Block()
  genesisBlock.setGenesisParams()
  this.putBlock(genesisBlock, function () {})
}

/**
 * Returns that head block
 * @method getHead
 * @param cb Function the callback
 */
Blockchain.prototype.getHead = function (name, cb) {
  if (typeof name === 'function') {
    cb = name
    name = 'vm'
  }

  if (!this._initDone) {
    this._pendingGets.push(arguments)
  } else {
    // if the head is not found return the rawHead
    var hash = this.meta.heads[name] || this.meta.rawHead
    this.getBlock(hash, cb)
  }
}

/**
 * Adds a block to the blockchain
 * @method addBlock
 * @param {object} block -the block to be added to the block chain
 * @param {function} cb - a callback function
 */
Blockchain.prototype.putBlock = function (block, cb) {
  if (!this._initDone) {
    this._pendingSaves.push([block, cb])
  } else {
    this._addBlock(block, cb)
  }
}

Blockchain.prototype.putBlocks = function (blocks, cb) {
  var self = this
  async.eachSeries(blocks, function (block, done) {
    self.putBlock(block, done)
  }, cb)
}

Blockchain.prototype._addBlock = function (block, cb) {
  var self = this
  var blockHash = block.hash().toString('hex')
  var parentDetails
  var dbOps = []

  if (block.constructor !== Block) {
    block = new Block(block)
  }

  async.series([

    function verify (cb2) {
      if (!self.validate) {
        return cb2()
      }

      if (self.meta.genesis && block.isGenesis()) {
        return cb2('already have genesis set')
      }

      block.validate(self, cb2)
    },
    function verifyPOW (cb2) {
      if (!self.validate) {
        return cb2()
      }

      self.ethash.verifyPOW(block, function (valid) {
        if (valid) {
          cb2()
        } else {
          cb2('invalid POW')
        }
      })
    },
    // look up the parent meta info
    function parentInfo (cb2) {
      // if genesis block
      if (block.isGenesis()) {
        return cb2()
{'fraction_non_alphanumeric': 0.12409432222368594, 'fraction_numerical': 0.003029903833487024, 'mean_word_length': 2.5278810408921935, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, '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': '840261', 'n_tokens_mistral': 2410, 'n_tokens_neox': 2382, 'n_words': 689}