code: function parseBlockResults (err) {
      if (err) {
        if (checkpointedState) {
          self.stateManager.revert(function () {
            cb(err)
          })
        } else {
          cb(err)
        }
        return
      }
  
      self.stateManager.commit(function (err) {
        if (err) return cb(err)
  
        self.stateManager.getStateRoot(function (err, stateRoot) {
          if (err) return cb(err)
  
          // credit all block rewards
          if (generateStateRoot) {
            block.header.stateRoot = stateRoot
          }
  
          if (validateStateRoot) {
            if (receiptTrie.root && receiptTrie.root.toString('hex') !== block.header.receiptTrie.toString('hex')) {
              err = new Error((err || '') + 'invalid receiptTrie ')
            }
            if (bloom.bitvector.toString('hex') !== block.header.bloom.toString('hex')) {
              err = new Error((err || '') + 'invalid bloom ')
            }
            if (ethUtil.bufferToInt(block.header.gasUsed) !== Number(gasUsed)) {
              err = new Error((err || '') + 'invalid gasUsed ')
            }
            if (stateRoot.toString('hex') !== block.header.stateRoot.toString('hex')) {
              err = new Error((err || '') + 'invalid block stateRoot ')
            }
          }
  
          result = {
            receipts: receipts,
            results: txResults,
            error: err
          }
  
          afterBlock(cb.bind(this, err, result))
        })
      })
    }
docs: handle results or error from block run