Skip to content

Commit 0d3f264

Browse files
committed
add contract state manipulation to the test, add test for replaying from a snapshot, fix bugs that bubbled up as a result
1 parent cdbe373 commit 0d3f264

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

contracts/snapshot_test/snapshot_test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ namespace snapshot_test {
5656

5757
} else {
5858
data.modify( current, self, [&]( auto& r ) {
59-
r.id += value;
6059
r.index_f64 += value;
6160
r.index_f128 += value;
6261
r.index_i64 += value;

libraries/chain/block_log.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,12 @@ namespace eosio { namespace chain {
349349
genesis_state gs;
350350
fc::raw::unpack(my->block_stream, gs);
351351

352+
// skip the totem
353+
if (my->version > 1) {
354+
uint64_t totem;
355+
my->block_stream.read((char*) &totem, sizeof(totem));
356+
}
357+
352358
while( pos < end_pos ) {
353359
fc::raw::unpack(my->block_stream, tmp);
354360
my->block_stream.read((char*)&pos, sizeof(pos));

unittests/snapshot_tests.cpp

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ class snapshotted_tester : public base_tester {
3131
init(copied_config, snapshot);
3232
}
3333

34+
snapshotted_tester(controller::config config, const snapshot_reader_ptr& snapshot, int ordinal, int copy_block_log_from_ordinal) {
35+
FC_ASSERT(config.blocks_dir.filename().generic_string() != "."
36+
&& config.state_dir.filename().generic_string() != ".", "invalid path names in controller::config");
37+
38+
controller::config copied_config = config;
39+
copied_config.blocks_dir =
40+
config.blocks_dir.parent_path() / std::to_string(ordinal).append(config.blocks_dir.filename().generic_string());
41+
copied_config.state_dir =
42+
config.state_dir.parent_path() / std::to_string(ordinal).append(config.state_dir.filename().generic_string());
43+
44+
// create a copy of the desired block log and reversible
45+
auto block_log_path = config.blocks_dir.parent_path() / std::to_string(copy_block_log_from_ordinal).append(config.blocks_dir.filename().generic_string());
46+
fc::create_directories(copied_config.blocks_dir);
47+
fc::copy(block_log_path / "blocks.log", copied_config.blocks_dir / "blocks.log");
48+
fc::copy(block_log_path / config::reversible_blocks_dir_name, copied_config.blocks_dir / config::reversible_blocks_dir_name );
49+
50+
init(copied_config, snapshot);
51+
}
3452
signed_block_ptr produce_block( fc::microseconds skip_time = fc::milliseconds(config::block_interval_ms), uint32_t skip_flag = 0/*skip_missed_block_penalty*/ )override {
3553
return _produce_block(skip_time, false, skip_flag);
3654
}
@@ -45,7 +63,7 @@ class snapshotted_tester : public base_tester {
4563

4664
BOOST_AUTO_TEST_SUITE(snapshot_tests)
4765

48-
BOOST_AUTO_TEST_CASE(test_multi_index_snapshot)
66+
BOOST_AUTO_TEST_CASE(test_exhaustive_snapshot)
4967
{
5068
tester chain;
5169

@@ -56,8 +74,7 @@ BOOST_AUTO_TEST_CASE(test_multi_index_snapshot)
5674
chain.produce_blocks(1);
5775
chain.control->abort_block();
5876

59-
60-
static const int generation_count = 20;
77+
static const int generation_count = 8;
6178
std::list<snapshotted_tester> sub_testers;
6279

6380
for (int generation = 0; generation < generation_count; generation++) {
@@ -71,6 +88,9 @@ BOOST_AUTO_TEST_CASE(test_multi_index_snapshot)
7188
sub_testers.emplace_back(chain.get_config(), std::make_shared<variant_snapshot_reader>(snapshot), generation);
7289

7390
// increment the test contract
91+
chain.push_action(N(snapshot), N(increment), N(snapshot), mutable_variant_object()
92+
( "value", 1 )
93+
);
7494

7595
// produce block
7696
auto new_block = chain.produce_block();
@@ -88,4 +108,62 @@ BOOST_AUTO_TEST_CASE(test_multi_index_snapshot)
88108
}
89109
}
90110

111+
BOOST_AUTO_TEST_CASE(test_replay_over_snapshot)
112+
{
113+
tester chain;
114+
115+
chain.create_account(N(snapshot));
116+
chain.produce_blocks(1);
117+
chain.set_code(N(snapshot), snapshot_test_wast);
118+
chain.set_abi(N(snapshot), snapshot_test_abi);
119+
chain.produce_blocks(1);
120+
chain.control->abort_block();
121+
122+
static const int pre_snapshot_block_count = 12;
123+
static const int post_snapshot_block_count = 12;
124+
125+
for (int itr = 0; itr < pre_snapshot_block_count; itr++) {
126+
// increment the contract
127+
chain.push_action(N(snapshot), N(increment), N(snapshot), mutable_variant_object()
128+
( "value", 1 )
129+
);
130+
131+
// produce block
132+
chain.produce_block();
133+
}
134+
135+
chain.control->abort_block();
136+
auto expected_pre_integrity_hash = chain.control->calculate_integrity_hash();
137+
138+
// create a new snapshot child
139+
variant_snapshot_writer writer;
140+
auto writer_p = std::shared_ptr<snapshot_writer>(&writer, [](snapshot_writer *){});
141+
chain.control->write_snapshot(writer_p);
142+
auto snapshot = writer.finalize();
143+
144+
// create a new child at this snapshot
145+
snapshotted_tester snap_chain(chain.get_config(), std::make_shared<variant_snapshot_reader>(snapshot), 1);
146+
BOOST_REQUIRE_EQUAL(expected_pre_integrity_hash.str(), snap_chain.control->calculate_integrity_hash().str());
147+
148+
// push more blocks to build up a block log
149+
for (int itr = 0; itr < post_snapshot_block_count; itr++) {
150+
// increment the contract
151+
chain.push_action(N(snapshot), N(increment), N(snapshot), mutable_variant_object()
152+
( "value", 1 )
153+
);
154+
155+
// produce & push block
156+
snap_chain.push_block(chain.produce_block());
157+
}
158+
159+
// verify the hash at the end
160+
chain.control->abort_block();
161+
auto expected_post_integrity_hash = chain.control->calculate_integrity_hash();
162+
BOOST_REQUIRE_EQUAL(expected_post_integrity_hash.str(), snap_chain.control->calculate_integrity_hash().str());
163+
164+
// replay the block log from the snapshot child, from the snapshot
165+
snapshotted_tester replay_chain(chain.get_config(), std::make_shared<variant_snapshot_reader>(snapshot), 2, 1);
166+
BOOST_REQUIRE_EQUAL(expected_post_integrity_hash.str(), snap_chain.control->calculate_integrity_hash().str());
167+
}
168+
91169
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)