Ejemplo n.º 1
0
static int
do_update_set(const symboldb_options &opt, database &db, char **argv)
{
  database::package_set_id set = db.lookup_package_set(opt.set_name.c_str());
  if (set == database::package_set_id()) {
    fprintf(stderr, "error: package set \"%s\" does not exist\n",
	    opt.set_name.c_str());
    return 1;
  }

  typedef std::vector<database::package_id> pset;
  pset ids;
  {
    package_set_consolidator<database::package_id> psc;
    if (!load_rpms(opt, db, argv, psc)) {
      return 1;
    }
    ids = psc.values();
  }

  db.txn_begin();
  {
    database::advisory_lock lock
      (db.lock(database::PACKAGE_SET_LOCK_TAG, set.value()));
    if (db.update_package_set(set, ids)) {
      finalize_package_set(opt, db, set);
    }
  }
  db.txn_commit();
  return 0;
}
Ejemplo n.º 2
0
void isomorph::init_DB_level(database &D, INT level, INT verbose_level)
{
	INT f_v = (verbose_level >= 1);
	btree B1, B2;
	INT f_compress = TRUE;
	INT f_duplicatekeys = TRUE;
	INT i;

	if (f_v) {
		cout << "isomorph::init_DB_level level=" << level << endl;
		}
	sprintf(fname_db_level, "%sstarter_lvl_%ld.db", prefix, level);
	sprintf(fname_db_level_idx1, "%sstarter_lvl_%ld_a.idx", prefix, level);
	sprintf(fname_db_level_idx2, "%sstarter_lvl_%ld_b.idx", prefix, level);
	sprintf(fname_db_level_ge, "%sstarter_lvl_%ld_ge.bin", prefix, level);

	D.init(fname_db_level, VECTOR, f_compress);
	
	B1.init(fname_db_level_idx1, f_duplicatekeys, 0 /* btree_idx */);
	B1.add_key_INT4(0, 0); 
	D.btree_access().append(B1);

	B2.init(fname_db_level_idx2, f_duplicatekeys, 1 /* btree_idx */);
		// 2 up to 2+level-1 are the values of the starter (of size level)
	for (i = 0; i < level; i++) {
		B2.add_key_INT4(2 + i, 0);
		}
	D.btree_access().append(B2);
}
Ejemplo n.º 3
0
void refund_worker_type::pay_worker(share_type pay, database& db)
{
   total_burned += pay;
   db.modify(db.get(asset_id_type()).dynamic_data(db), [pay](asset_dynamic_data_object& d) {
      d.current_supply -= pay;
   });
}
Ejemplo n.º 4
0
static int
do_create_set(const symboldb_options &opt, database &db, char **argv)
{
  if (db.lookup_package_set(opt.set_name.c_str())
      != database::package_set_id()) {
    fprintf(stderr, "error: package set \"%s\" already exists\n",
	    opt.set_name.c_str());
    return 1;
  }

  typedef std::vector<database::package_id> pset;
  pset ids;
  {
    package_set_consolidator<database::package_id> psc;
    if (!load_rpms(opt, db, argv, psc)) {
      return 1;
    }
    ids = psc.values();
  }

  db.txn_begin();
  database::package_set_id set =
    db.create_package_set(opt.set_name.c_str());
  if (db.update_package_set(set, ids)) {
    finalize_package_set(opt, db, set);
  }
  db.txn_commit();
  return 0;
}
Ejemplo n.º 5
0
static void
load_zip(database &db,
	 database::contents_id cid, const rpm_file_entry &file)
{
  zip_file zip(&file.contents);
  std::vector<unsigned char> data;
  while (true) {
    try {
      if (!zip.next()) {
	break;
      }
    } catch (os_exception &e) {
      // FIXME: Use proper, zip_file-specific exception.
      // zip.name() is not necessarily valid at this point.
      db.add_java_error(cid, e.what(), "");
      // Exit the loop because the file is likely corrupted significantly.
      break;
    }
    try {
      zip.data(data);
    } catch (os_exception &e) {
      // FIXME: Use proper, zip_file-specific exception.
      db.add_java_error(cid, e.what(), zip.name());
    }
    if (java_class::has_signature(data)) {
      try {
	java_class jc(&data);
	db.add_java_class(cid, jc);
      } catch (java_class::exception &e) {
	db.add_java_error(cid, e.what(), zip.name());
      }
    }
  }
}
Ejemplo n.º 6
0
 void apply(database &db, const operation &o, const options_type &opts) {
     auto undo_session = db.start_undo_session(!(opts &
                                                 skip_undo_operation));
     db.pre_apply_operation(o);
     o.visit(apply_operation_visitor(db, opts));
     db.post_apply_operation(o);
     undo_session.squash();
 }
Ejemplo n.º 7
0
solution_id add_solution(database& db, assignment_id assignment, std::vector<student_id> solvers,
		std::vector<task> editied_tasks) {
	auto id = db.new_solution_id();
	for(auto solver: solvers) {
		db.get_student(solver).add_solution(id);
	}
	auto tmp = solution{assignment, id, std::move(solvers), std::move(editied_tasks)};
	db.add_solution(std::move(tmp));
	return id;
}
Ejemplo n.º 8
0
static int
do_show_soname_conflicts(const symboldb_options &opt, database &db)
{
  database::package_set_id pset = db.lookup_package_set(opt.set_name.c_str());
  if (pset > database::package_set_id()) {
    db.print_elf_soname_conflicts(pset);
    return 0;
  } else {
    fprintf(stderr, "error: invalid package set: %s\n", opt.set_name.c_str());
    return 1;
  }
}
Ejemplo n.º 9
0
static void
add_files(const symboldb_options &opt, database &db, python_analyzer &pya,
	  const rpm_package_info &pkginfo, database::package_id pkg,
	  const char *rpm_path, rpm_file_entry &file)
{
  std::vector<unsigned char> digest;
  std::vector<unsigned char> preview;
  prepare_load(rpm_path, file, digest, preview);

  file.infos.front().normalize_name();

  database::file_id fid;
  database::contents_id cid;
  database::attribute_id aid;
  bool added;
  int contents_length;
  db.add_file(pkg, file.infos.front(), digest, preview, fid, cid,
	      added, contents_length);

  bool looks_like_python =
    unpack_files(pkginfo) && is_python_path(file.infos.front());

  if (file.infos.size() > 1) {
    assert(!file.infos.front().ghost());
    for (std::vector<rpm_file_info>::iterator
	 p = file.infos.begin() + 1, end = file.infos.end();
	 p != end; ++p) {
      assert(!p->ghost());
      p->normalize_name();
      aid = db.intern_file_attribute(*p);
      db.add_file(pkg, p->name, p->mtime, p->ino, cid, aid);
      looks_like_python = looks_like_python
	|| (unpack_files(pkginfo) && is_python_path(file.infos.front()));
    }
  }

  if (added) {
    if (unpack_files(pkginfo)) {
      do_load_formats(opt, db, pya, cid, file);
    }
  } else {
    // We might recognize additonal files as Python files if they are
    // loaded later under a different name.
    if (looks_like_python) {
      load_python(opt, db, pya, cid, file);
    }
  }
  // If the contents in the database was truncated, update it with the
  // longer version.
  if (static_cast<size_t>(contents_length) < preview.size()) {
    db.update_contents_preview(cid, preview);
  }
}
Ejemplo n.º 10
0
static int
do_run_example(const symboldb_options &opt, database &db, char **argv)
{
  int errors = 0;
  while (*argv) {
    file_handle file(*argv, "r");
    file_handle::line line_handle;
    std::string current;
    unsigned lineno = 0;
    unsigned start_lineno;
    try {
      while (file.getline(line_handle)) {
	++lineno;
	std::string line(line_handle.str());
	bool start = current.empty();
	if (starts_with(line, "    ")) {
	  current += "      ";
	  current.append(line.begin() + 4, line.end());
	} else if (starts_with(line, "\t")) {
	  current.append(line.begin() + 1, line.end());
	} else if (!current.empty()) {
	  if (opt.output != symboldb_options::quiet) {
	    fprintf(stderr, "info: executing %s:%u\n", *argv, start_lineno);
	  }
	  db.exec_sql(current.c_str());
	  current.clear();
	  start = false;
	} else {
	  start = false;
	}
	if (start && !current.empty()) {
	  start_lineno = lineno;
	}
      }
      if (!current.empty()) {
	if (opt.output != symboldb_options::quiet) {
	  fprintf(stderr, "info: executing %s:%u\n", *argv, start_lineno);
	}
	db.exec_sql(current.c_str());
      }
    } catch (pg_exception &e) {
      dump("error: ", e, stderr);
      ++errors;
    }
    ++argv;
  }
  if (errors > 0) {
    return 1;
  } else {
    return 0;
  }
}
Ejemplo n.º 11
0
// Return a sorted vector of all table numbers.
std::vector<table::Number> get_all_tables_numbers(database const& table_file)
{
    int const tables_count = table_file.tables_count();
    std::vector<table::Number> numbers;
    numbers.reserve(tables_count);
    for(int i = 0; i != tables_count; ++i)
        {
        numbers.push_back(table_file.get_nth_table(i).number());
        }

    std::sort(numbers.begin(), numbers.end());

    return numbers;
}
Ejemplo n.º 12
0
static database::package_id
load_rpm_internal(const symboldb_options &opt, database &db,
		  const char *rpm_path, rpm_package_info &pkginfo)
{
  rpm_parser rpmparser(rpm_path);
  python_analyzer pya;
  pkginfo = rpmparser.package();
  // We can destroy the lock immediately because we are running in a
  // transaction.
  lock_rpm(db, pkginfo);
  rpm_file_entry file;

  database::package_id pkg;
  if (!db.intern_package(rpmparser.package(), pkg)) {
    if (opt.output != symboldb_options::quiet) {
      fprintf(stderr, "info: skipping %s from %s\n",
	      rpmparser.nevra(), rpm_path);
    }
    return pkg;
  }

  if (opt.output != symboldb_options::quiet) {
    fprintf(stderr, "info: loading %s from %s\n", rpmparser.nevra(), rpm_path);
  }

  dependencies(opt, db, pkg, rpmparser);
  scripts(opt, db, pkg, rpmparser);
  triggers(opt, db, pkg, rpmparser);

  // FIXME: We should not read arbitrary files into memory, only ELF
  // files.
  while (rpmparser.read_file(file)) {
    if (file.infos.size() > 1) {
      // Hard links, so this is a real file.
      add_files(opt, db, pya, pkginfo, pkg, rpm_path, file);
      continue;
    }

    assert(!file.infos.empty());
    rpm_file_info &info(file.infos.front());
    if (info.is_directory()) {
      db.add_directory(pkg, info);
    } else if (info.is_symlink()) {
      db.add_symlink(pkg, info);
    } else {
      add_files(opt, db, pya, pkginfo, pkg, rpm_path, file);
    }
  }
  return pkg;
}
Ejemplo n.º 13
0
database::package_id
rpm_load(const symboldb_options &opt, database &db,
	 const char *path, rpm_package_info &info,
	 const checksum *expected, const char *url)
{
  if (expected && (expected->type != hash_sink::sha256
		   && expected->type != hash_sink::sha1)) {
    raise<std::runtime_error>("unsupported hash type");
  }

  // Unreferenced RPMs should not be visible to analyzers, so we can
  // load each RPM in a separate transaction.  We make a synchronous
  // commit when referencing the RPM data, so a non-synchronous commit
  // is sufficient here.
  db.txn_begin_no_sync();
  database::package_id pkg = load_rpm_internal(opt, db, path, info);

  hash_sink sha256(hash_sink::sha256);
  hash_sink sha1(hash_sink::sha1);
  {
    fd_handle handle;
    handle.open_read_only(path);
    fd_source source(handle.get());
    tee_sink tee(&sha256, &sha1);
    copy_source_to_sink(source, tee);
  }
  assert(sha256.octets() == sha1.octets());

  std::vector<unsigned char> digest;
  sha256.digest(digest);
  db.add_package_digest(pkg, digest, sha256.octets());
  if (expected && expected->type == hash_sink::sha256
      && expected->value != digest) {
    raise<std::runtime_error>("checksum mismatch");
  }
  sha1.digest(digest);
  db.add_package_digest(pkg, digest, sha1.octets());
  if (expected && expected->type == hash_sink::sha1
      && expected->value != digest) {
    raise<std::runtime_error>("checksum mismatch");
  }
  if (url != NULL) {
    db.add_package_url(pkg, url);
  }

  db.txn_commit();
  return pkg;
}
Ejemplo n.º 14
0
bool _is_authorized_asset(
   const database& d,
   const account_object& acct,
   const asset_object& asset_obj)
{
   if( acct.allowed_assets.valid() )
   {
      if( acct.allowed_assets->find( asset_obj.id ) == acct.allowed_assets->end() )
         return false;
      // must still pass other checks even if it is in allowed_assets
   }

   for( const auto id : acct.blacklisting_accounts )
   {
      if( asset_obj.options.blacklist_authorities.find(id) != asset_obj.options.blacklist_authorities.end() )
         return false;
   }

   if( d.head_block_time() > HARDFORK_415_TIME )
   {
      if( asset_obj.options.whitelist_authorities.size() == 0 )
         return true;
   }

   for( const auto id : acct.whitelisting_accounts )
   {
      if( asset_obj.options.whitelist_authorities.find(id) != asset_obj.options.whitelist_authorities.end() )
         return true;
   }

   return false;
}
Ejemplo n.º 15
0
	void open(string *filename) {
		db.init(*filename);
		db << "PRAGMA synchronous = OFF;";
		db << "CREATE TABLE IF NOT EXISTS metadata (name text, value text, UNIQUE (name));";
		db << "CREATE TABLE IF NOT EXISTS tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob, UNIQUE (zoom_level, tile_column, tile_row));";
		db << "BEGIN;"; // begin a transaction
	}
Ejemplo n.º 16
0
void
expire(const symboldb_options &opt, database &db)
{
  if (opt.output != symboldb_options::quiet) {
    fprintf(stderr, "info: expiring URL cache\n");
  }
  db.expire_url_cache();

  if (opt.output != symboldb_options::quiet) {
    fprintf(stderr, "info: expiring unreferenced packages\n");
  }
  db.expire_packages();

  if (opt.output != symboldb_options::quiet) {
    fprintf(stderr, "info: expiring file contents\n");
  }
  db.expire_file_contents();

  if (opt.output != symboldb_options::quiet) {
    fprintf(stderr, "info: expiring java classes\n");
  }
  db.expire_java_classes();

  if (opt.output != symboldb_options::quiet) {
    fprintf(stderr, "info: expiring unused RPMs\n");
  }
  {
    typedef std::vector<std::vector<unsigned char> > digvec;
    std::tr1::shared_ptr<file_cache> fcache(opt.rpm_cache());
    digvec fcdigests;
    fcache->digests(fcdigests);
    std::sort(fcdigests.begin(), fcdigests.end());
    digvec dbdigests;
    db.referenced_package_digests(dbdigests);
    digvec result;
    std::set_difference(fcdigests.begin(), fcdigests.end(),
			dbdigests.begin(), dbdigests.end(),
			std::back_inserter(result));
    fd_handle dir;
    dir.open_directory(opt.rpm_cache_path().c_str());
    for (digvec::iterator p = result.begin(), end = result.end();
	 p != end; ++p) {
      dir.unlinkat(base16_encode(p->begin(), p->end()).c_str(), 0);
    }
  }
}
Ejemplo n.º 17
0
void open_test_database( database& db, const fc::path& dir )
{
   database::open_args args;
   args.data_dir = dir;
   args.shared_mem_dir = dir;
   args.initial_supply = INITIAL_TEST_SUPPLY;
   args.shared_file_size = TEST_SHARED_MEM_SIZE;
   db.open( args );
}
Ejemplo n.º 18
0
static void
dependencies(const symboldb_options &, database &db,
	     database::package_id pkg, rpm_parser &rpmparser)
{
  const std::vector<rpm_dependency> &deps(rpmparser.dependencies());
  for (std::vector<rpm_dependency>::const_iterator
	 p = deps.begin(), end = deps.end(); p != end; ++p) {
    db.add_package_dependency(pkg, *p);
  }
}
Ejemplo n.º 19
0
  part::part(const database& db, sqlite3_stmt* row)
  {
    int id = sqlite3_column_int(row, 0);

    type_ = static_cast<part_type>(sqlite3_column_int(row, 3));

    switch (type_)
    {
      case part_type::noun_phrase:
      {
        new(&noun_phrase_.role) std::string(reinterpret_cast<const char*>(sqlite3_column_blob(row, 4)));
        new(&noun_phrase_.selrestrs) std::set<std::string>(db.selrestrs(id));
        new(&noun_phrase_.synrestrs) std::set<std::string>(db.synrestrs(id));

        break;
      }

      case part_type::preposition:
      {
        std::string serializedChoices(reinterpret_cast<const char*>(sqlite3_column_blob(row, 5)));
        new(&preposition_.choices) std::vector<std::string>(split<std::vector<std::string>>(serializedChoices, ","));
        
        preposition_.literal = (sqlite3_column_int(row, 6) == 1);

        break;
      }

      case part_type::literal:
      {
        new(&literal_) std::string(reinterpret_cast<const char*>(sqlite3_column_blob(row, 7)));

        break;
      }

      case part_type::verb:
      case part_type::adjective:
      case part_type::adverb:
      case part_type::invalid:
      {
        break;
      }
    }
  }
Ejemplo n.º 20
0
void with_skip_flags(
   database& db,
   uint32_t skip_flags,
   Lambda callback )
{
   node_property_object& npo = db.node_properties();
   skip_flags_restorer restorer( npo, npo.skip_flags );
   npo.skip_flags = skip_flags;
   callback();
   return;
}
Ejemplo n.º 21
0
static void
scripts(const symboldb_options &, database &db,
	database::package_id pkg, rpm_parser &rpmparser)
{
  std::vector<rpm_script> scripts;
  rpmparser.scripts(scripts);
  for (std::vector<rpm_script>::const_iterator
	 p = scripts.begin(), end = scripts.end(); p != end; ++p) {
    db.add_package_script(pkg, *p);
  }
}
Ejemplo n.º 22
0
        void apply(database &db, const signed_transaction &t, const options_type &opts) {
            auto undo_session = db.start_undo_session(!(opts &
                                                        skip_undo_transaction));
            db.pre_apply_transaction(t);

            db.create<transaction_object>([&](transaction_object &trx) {
                trx.trx_id = t.id();
                trx.block_num = db.head_block().block_num;
                auto pack_size = fc::raw::pack_size(t);
                trx.packed_transaction.resize(pack_size);
                fc::datastream<char *> ds(trx.packed_transaction.data(), pack_size);
                fc::raw::pack(ds, t);
            });

            for (const auto &op : t.operations) {
                apply(db, op, opts);
            }

            db.post_apply_transaction(t);
            undo_session.squash();
        }
Ejemplo n.º 23
0
void evaluate_buyback_account_options( const database& db, const buyback_account_options& bbo )
{
   FC_ASSERT( db.head_block_time() >= HARDFORK_538_TIME );
   const asset_object& a = bbo.asset_to_buy(db);
   GRAPHENE_ASSERT( a.issuer == bbo.asset_to_buy_issuer,
      account_create_buyback_incorrect_issuer, "Incorrect asset issuer specified in buyback_account_options", ("asset", a)("bbo", bbo) );
   GRAPHENE_ASSERT( !a.buyback_account.valid(),
      account_create_buyback_already_exists, "Cannot create buyback for asset which already has buyback", ("asset", a)("bbo", bbo) );
   // TODO:  Replace with chain parameter #554
   GRAPHENE_ASSERT( bbo.markets.size() < GRAPHENE_DEFAULT_MAX_BUYBACK_MARKETS,
      account_create_buyback_too_many_markets, "Too many buyback markets", ("asset", a)("bbo", bbo) );
}
Ejemplo n.º 24
0
// Loads python source code.
static void
load_python(const symboldb_options &, database &db, python_analyzer &pya,
	    database::contents_id cid, const rpm_file_entry &file)
{
  if (db.has_python_analysis(cid)) {
    return;
  }
  if (!pya.parse(file.contents)) {
    db.add_python_error(cid, pya.error_line(), pya.error_message().c_str());
    return;
  }
  for (std::vector<std::string>::const_iterator
	 p = pya.imports().begin(), end = pya.imports().end(); p != end; ++p) {
    db.add_python_import(cid, p->c_str());
  }
  for (std::vector<std::string>::const_iterator
	 p = pya.attributes().begin(), end = pya.attributes().end();
       p != end; ++p) {
    db.add_python_attribute(cid, p->c_str());
  }
  for (std::vector<std::string>::const_iterator
	 p = pya.functions().begin(), end = pya.functions().end();
       p != end; ++p) {
    db.add_python_function_def(cid, p->c_str());
  }
  for (std::vector<std::string>::const_iterator
	 p = pya.classes().begin(), end = pya.classes().end();
       p != end; ++p) {
    db.add_python_class_def(cid, p->c_str());
  }
}
Ejemplo n.º 25
0
void vesting_balance_worker_type::initializer::init(database& db, const worker_object& obj, vesting_balance_worker_type& worker) const
{
   worker.balance = db.create<vesting_balance_object>([&](vesting_balance_object& b) {
         b.owner = obj.worker_account;
         b.balance = asset(0);

         cdd_vesting_policy policy;
         policy.vesting_seconds = fc::days(pay_vesting_period_days).to_seconds();
         policy.coin_seconds_earned = 0;
         policy.coin_seconds_earned_last_update = db.head_block_time();
         b.policy = policy;
   }).id;
}
Ejemplo n.º 26
0
static void
triggers(const symboldb_options &, database &db,
	 database::package_id pkg, rpm_parser &rpmparser)
{
  std::vector<rpm_trigger> triggers;
  rpmparser.triggers(triggers);
  int i = 0;
  for (std::vector<rpm_trigger>::const_iterator
	 p = triggers.begin(), end = triggers.end(); p != end; ++p) {
    db.add_package_trigger(pkg, *p, i);
    ++i;
  }
}
Ejemplo n.º 27
0
bool proposal_object::is_authorized_to_execute(database& db) const
{
   transaction_evaluation_state dry_run_eval(&db);

   try {
      bool allow_non_immediate_owner = ( db.head_block_time() >= HARDFORK_CORE_584_TIME );
      verify_authority( proposed_transaction.operations, 
                        available_key_approvals,
                        [&]( account_id_type id ){ return &id(db).active; },
                        [&]( account_id_type id ){ return &id(db).owner;  },
                        allow_non_immediate_owner,
                        db.get_global_properties().parameters.max_authority_depth,
                        true, /* allow committeee */
                        available_active_approvals,
                        available_owner_approvals );
   } 
   catch ( const fc::exception& e )
   {
      return false;
   }
   return true;
}
Ejemplo n.º 28
0
void assignment::print_results(const std::vector<student_id>& students, database& db) const {
	std::cout << "\"Name\", \"id\", ";
	for(auto&& task: m_max_points) {
		std::cout << '"' << task.first << "\", ";
	}
	std::cout << '\n';
	for (auto stud: students) {
		const auto& student = db.get_student(stud);
		const auto& solutions = student.solutions();
		auto it = std::find_if(begin(solutions), end(solutions),
		                       [&](const auto& sol) {return db.get_solution(sol).assignment() == m_id;});
		if (it == end(solutions)) {
			continue;
		}
		const auto& solution = db.get_solution(*it);
		std::cout << '"' << student.name() << "\", \"" << student.id() << "\", ";
		for(auto&& task: m_max_points) {
			std::cout << '"' << solution.get_task(task.first).points() << "\", ";
		}
		std::cout << '\n';
	}
}
Ejemplo n.º 29
0
// Loads XML-like content.
static void
load_xml(const symboldb_options &, database &db,
	 database::contents_id cid, const rpm_file_entry &file)
{
  vector_source src(&file.contents);
  expat_source source(&src);

  // Extract URLs from POM files.
  std::vector<maven_url> result;
  try {
    maven_url::extract(source, result);
  } catch (expat_source::malformed &e) {
    std::vector<unsigned char> before(e.before().begin(), e.before().end());
    std::vector<unsigned char> after(e.after().begin(), e.after().end());
    db.add_xml_error(cid, e.message(), e.line(), before, after);
  }
  for (std::vector<maven_url>::const_iterator
	 p = result.begin(), end = result.end();
       p != end; ++p) {
      db.add_maven_url(cid, *p);
  }
}
Ejemplo n.º 30
0
        void apply(database &db, const signed_block &b, const options_type &opts) {
            auto undo_session = db.start_undo_session(!(opts &
                                                        skip_undo_block));
            db.pre_apply_block(b);

            if (!(opts & skip_validation)) {
                FC_ASSERT(b.timestamp.sec_since_epoch() % 3 == 0);
                if (b.block_num() > 1) {
                    idump((b.block_num()));
                    const auto &head = db.head_block();
                    FC_ASSERT(b.block_num() == head.block_num + 1);
                    FC_ASSERT(b.timestamp >= head.timestamp + fc::seconds(3));
                }
            }

            db.create<block_object>([&](block_object &obj) {
                obj.block_num = b.block_num();
                obj.block_id = b.id();
                obj.ref_prefix = obj.block_id._hash[1];
                obj.previous = b.previous;
                obj.timestamp = b.timestamp;
                obj.witness = b.witness;
                obj.transaction_merkle_root = b.transaction_merkle_root;
                obj.witness_signature = b.witness_signature;

                obj.transactions.reserve(b.transactions.size());
                for (const auto &t : b.transactions) {
                    obj.transactions.emplace_back(t.id());
                }
            });

            for (const auto &trx : b.transactions) {
                apply(db, trx, opts);
            }

            db.post_apply_block(b);
            undo_session.push();
        }