Skip to content

Commit 94510b6

Browse files
committed
plumbing for loading/restoring from snapshot
1 parent 89cdf62 commit 94510b6

File tree

7 files changed

+55
-38
lines changed

7 files changed

+55
-38
lines changed

libraries/chain/authorization_manager.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,19 @@ namespace eosio { namespace chain {
4242
});
4343
}
4444

45-
void authorization_manager::add_to_snapshot( snapshot_writer& snapshot ) const {
45+
void authorization_manager::add_to_snapshot( const snapshot_writer_ptr& snapshot ) const {
4646
authorization_index_set::walk_indices([this, &snapshot]( auto utils ){
47-
snapshot.write_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ){
47+
snapshot->write_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ){
4848
decltype(utils)::walk(_db, [&section]( const auto &row ) {
4949
section.add_row(row);
5050
});
5151
});
5252
});
5353
}
5454

55-
void authorization_manager::read_from_snapshot( snapshot_reader& snapshot ) {
55+
void authorization_manager::read_from_snapshot( const snapshot_reader_ptr& snapshot ) {
5656
authorization_index_set::walk_indices([this, &snapshot]( auto utils ){
57-
snapshot.read_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ) {
57+
snapshot->read_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ) {
5858
bool done = section.empty();
5959
while(!done) {
6060
decltype(utils)::create(_db, [&section]( auto &row ) {

libraries/chain/controller.cpp

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424

2525
#include <eosio/chain/eosio_contract.hpp>
2626

27-
#include <eosio/chain/database_utils.hpp>
28-
#include <eosio/chain/snapshot.hpp>
29-
3027
namespace eosio { namespace chain {
3128

3229
using resource_limits::resource_limits_manager;
@@ -149,6 +146,7 @@ struct controller_impl {
149146
}
150147

151148
if ( read_mode == db_read_mode::SPECULATIVE ) {
149+
EOS_ASSERT( head->block && head->block->transactions.size() == head->trxs.size(), block_validate_exception, "attempting to pop a block that was sparsely loaded from a snapshot");
152150
for( const auto& t : head->trxs )
153151
unapplied_transactions[t->signed_id] = t;
154152
}
@@ -266,15 +264,14 @@ struct controller_impl {
266264
emit( self.irreversible_block, s );
267265
}
268266

269-
void init() {
267+
void init(const snapshot_reader_ptr& snapshot) {
270268

271-
/**
272-
* The fork database needs an initial block_state to be set before
273-
* it can accept any new blocks. This initial block state can be found
274-
* in the database (whose head block state should be irreversible) or
275-
* it would be the genesis state.
276-
*/
277-
if( !head ) {
269+
if (snapshot) {
270+
EOS_ASSERT(!head, fork_database_exception, "");
271+
272+
read_from_snapshot(snapshot);
273+
274+
} else if( !head ) {
278275
initialize_fork_db(); // set head to genesis state
279276

280277
auto end = blog.read_head();
@@ -325,7 +322,7 @@ struct controller_impl {
325322
("head",head->block_num)("unconfimed", objitr->blocknum) );
326323
} else {
327324
auto end = blog.read_head();
328-
EOS_ASSERT( end && end->block_num() == head->block_num, fork_database_exception,
325+
EOS_ASSERT( !end || end->block_num() == head->block_num, fork_database_exception,
329326
"fork database exists but reversible block database does not, replay blockchain",
330327
("blog_head",end->block_num())("head",head->block_num) );
331328
}
@@ -451,9 +448,13 @@ struct controller_impl {
451448
int cur_row;
452449
};
453450

454-
void add_to_snapshot( snapshot_writer& snapshot ) const {
451+
void add_to_snapshot( const snapshot_writer_ptr& snapshot ) const {
452+
snapshot->write_section<block_state>([this]( auto &section ){
453+
section.template add_row<block_header_state>(*fork_db.head());
454+
});
455+
455456
controller_index_set::walk_indices([this, &snapshot]( auto utils ){
456-
snapshot.write_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ){
457+
snapshot->write_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ){
457458
decltype(utils)::walk(db, [&section]( const auto &row ) {
458459
section.add_row(row);
459460
});
@@ -466,13 +467,25 @@ struct controller_impl {
466467

467468
void print_json_snapshot() const {
468469
json_snapshot_writer snapshot;
469-
add_to_snapshot(snapshot);
470+
auto snapshot_ptr = shared_ptr<snapshot_writer>(&snapshot, [](snapshot_writer *) {});
471+
add_to_snapshot(snapshot_ptr);
470472
std::cerr << fc::json::to_pretty_string(snapshot.snapshot) << std::endl;
471473
}
472474

473-
void read_from_snapshot( snapshot_reader& snapshot ) {
475+
void read_from_snapshot( const snapshot_reader_ptr& snapshot ) {
476+
snapshot->read_section<block_state>([this]( auto &section ){
477+
block_header_state head_header_state;
478+
section.read_row(head_header_state);
479+
480+
auto head_state = std::make_shared<block_state>(head_header_state);
481+
fork_db.set(head_state);
482+
fork_db.set_validity(head_state, true);
483+
fork_db.mark_in_current_chain(head_state, true);
484+
head = head_state;
485+
});
486+
474487
controller_index_set::walk_indices([this, &snapshot]( auto utils ){
475-
snapshot.read_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ) {
488+
snapshot->read_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ) {
476489
bool done = section.empty();
477490
while(!done) {
478491
decltype(utils)::create(db, [&section]( auto &row ) {
@@ -484,6 +497,8 @@ struct controller_impl {
484497

485498
authorization.read_from_snapshot(snapshot);
486499
resource_limits.read_from_snapshot(snapshot);
500+
501+
db.set_revision( head->block_num );
487502
}
488503

489504
/**
@@ -1490,7 +1505,7 @@ controller::~controller() {
14901505
}
14911506

14921507

1493-
void controller::startup() {
1508+
void controller::startup( const snapshot_reader_ptr& snapshot ) {
14941509

14951510
// ilog( "${c}", ("c",fc::json::to_pretty_string(cfg)) );
14961511
my->add_indices();
@@ -1499,7 +1514,7 @@ void controller::startup() {
14991514
if( !my->head ) {
15001515
elog( "No head block in fork db, perhaps we need to replay" );
15011516
}
1502-
my->init();
1517+
my->init(snapshot);
15031518
}
15041519

15051520
chainbase::database& controller::db()const { return my->db; }
@@ -1665,15 +1680,15 @@ const global_property_object& controller::get_global_properties()const {
16651680

16661681
signed_block_ptr controller::fetch_block_by_id( block_id_type id )const {
16671682
auto state = my->fork_db.get_block(id);
1668-
if( state ) return state->block;
1683+
if( state && state->block ) return state->block;
16691684
auto bptr = fetch_block_by_number( block_header::num_from_id(id) );
16701685
if( bptr && bptr->id() == id ) return bptr;
16711686
return signed_block_ptr();
16721687
}
16731688

16741689
signed_block_ptr controller::fetch_block_by_number( uint32_t block_num )const { try {
16751690
auto blk_state = my->fork_db.get_block_in_current_chain_by_num( block_num );
1676-
if( blk_state ) {
1691+
if( blk_state && blk_state->block ) {
16771692
return blk_state->block;
16781693
}
16791694

libraries/chain/include/eosio/chain/authorization_manager.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ namespace eosio { namespace chain {
2929
void add_indices();
3030
void initialize_database();
3131
void calculate_integrity_hash( fc::sha256::encoder& enc ) const;
32-
void add_to_snapshot( snapshot_writer& snapshot ) const;
33-
void read_from_snapshot( snapshot_reader& snapshot );
32+
void add_to_snapshot( const snapshot_writer_ptr& snapshot ) const;
33+
void read_from_snapshot( const snapshot_reader_ptr& snapshot );
3434

3535
const permission_object& create_permission( account_name account,
3636
permission_name name,

libraries/chain/include/eosio/chain/controller.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <eosio/chain/abi_serializer.hpp>
88
#include <eosio/chain/account_object.hpp>
9+
#include <eosio/chain/snapshot.hpp>
910

1011
namespace chainbase {
1112
class database;
@@ -85,7 +86,7 @@ namespace eosio { namespace chain {
8586
controller( const config& cfg );
8687
~controller();
8788

88-
void startup();
89+
void startup( const snapshot_reader_ptr& snapshot = nullptr );
8990

9091
/**
9192
* Starts a new pending block session upon which new transactions can

libraries/chain/include/eosio/chain/resource_limits.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ namespace eosio { namespace chain { namespace resource_limits {
4545
void add_indices();
4646
void initialize_database();
4747
void calculate_integrity_hash( fc::sha256::encoder& enc ) const;
48-
void add_to_snapshot( snapshot_writer& snapshot ) const;
49-
void read_from_snapshot( snapshot_reader& snapshot );
48+
void add_to_snapshot( const snapshot_writer_ptr& snapshot ) const;
49+
void read_from_snapshot( const snapshot_reader_ptr& snapshot );
5050

5151
void initialize_account( const account_name& account );
5252
void set_block_parameters( const elastic_limit_parameters& cpu_limit_parameters, const elastic_limit_parameters& net_limit_parameters );

libraries/chain/include/eosio/chain/snapshot.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,14 @@
99
#include <boost/core/demangle.hpp>
1010
#include <ostream>
1111

12-
1312
namespace eosio { namespace chain {
14-
1513
template<typename T>
1614
struct snapshot_section_traits {
1715
static std::string section_name() {
1816
return boost::core::demangle(typeid(T).name());
1917
}
2018
};
2119

22-
2320
template<typename T>
2421
struct snapshot_row_traits {
2522
using row_type = std::decay_t<T>;
@@ -44,7 +41,7 @@ namespace eosio { namespace chain {
4441

4542
template<typename T>
4643
struct snapshot_row_writer : abstract_snapshot_row_writer {
47-
explicit snapshot_row_writer( const T& data)
44+
explicit snapshot_row_writer( const T& data )
4845
:data(data) {}
4946

5047
void write(std::ostream& out) const override {
@@ -99,6 +96,8 @@ namespace eosio { namespace chain {
9996
virtual void write_end_section() = 0;
10097
};
10198

99+
using snapshot_writer_ptr = std::shared_ptr<snapshot_writer>;
100+
102101
namespace detail {
103102
struct abstract_snapshot_row_reader {
104103
virtual void provide(std::istream& in) const = 0;
@@ -175,4 +174,6 @@ namespace eosio { namespace chain {
175174
virtual void clear_section() = 0;
176175
};
177176

177+
using snapshot_reader_ptr = std::shared_ptr<snapshot_reader>;
178+
178179
}}

libraries/chain/resource_limits.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,19 @@ void resource_limits_manager::calculate_integrity_hash( fc::sha256::encoder& enc
7272
});
7373
}
7474

75-
void resource_limits_manager::add_to_snapshot( snapshot_writer& snapshot ) const {
75+
void resource_limits_manager::add_to_snapshot( const snapshot_writer_ptr& snapshot ) const {
7676
resource_index_set::walk_indices([this, &snapshot]( auto utils ){
77-
snapshot.write_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ){
77+
snapshot->write_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ){
7878
decltype(utils)::walk(_db, [&section]( const auto &row ) {
7979
section.add_row(row);
8080
});
8181
});
8282
});
8383
}
8484

85-
void resource_limits_manager::read_from_snapshot( snapshot_reader& snapshot ) {
85+
void resource_limits_manager::read_from_snapshot( const snapshot_reader_ptr& snapshot ) {
8686
resource_index_set::walk_indices([this, &snapshot]( auto utils ){
87-
snapshot.read_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ) {
87+
snapshot->read_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ) {
8888
bool done = section.empty();
8989
while(!done) {
9090
decltype(utils)::create(_db, [&section]( auto &row ) {

0 commit comments

Comments
 (0)