Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
tester.cpp
Go to the documentation of this file.
1#include <boost/test/unit_test.hpp>
2#include <boost/algorithm/string/predicate.hpp>
8#include <boost/iostreams/filtering_stream.hpp>
9#include <boost/iostreams/copy.hpp>
10#include <boost/iostreams/filter/gzip.hpp>
11
12#include <fstream>
13
14#include <contracts.hpp>
15
16namespace bio = boost::iostreams;
17
19 return sysio::chain::asset::from_string(s + " " CORE_SYMBOL_NAME);
20}
21
22namespace sysio { namespace testing {
23 std::string read_wast( const char* fn ) {
24 std::ifstream wast_file(fn);
25 FC_ASSERT( wast_file.is_open(), "wast file cannot be found" );
26 wast_file.seekg(0, std::ios::end);
27 std::vector<char> wast;
28 int len = wast_file.tellg();
29 FC_ASSERT( len >= 0, "wast file length is -1" );
30 wast.resize(len+1);
31 wast_file.seekg(0, std::ios::beg);
32 wast_file.read(wast.data(), wast.size());
33 wast[wast.size()-1] = '\0';
34 wast_file.close();
35 return {wast.data()};
36 }
37
38 std::vector<uint8_t> read_wasm( const char* fn ) {
39 std::ifstream wasm_file(fn, std::ios::binary);
40 FC_ASSERT( wasm_file.is_open(), "wasm file cannot be found" );
41 wasm_file.seekg(0, std::ios::end);
42 std::vector<uint8_t> wasm;
43 int len = wasm_file.tellg();
44 FC_ASSERT( len >= 0, "wasm file length is -1" );
45 wasm.resize(len);
46 wasm_file.seekg(0, std::ios::beg);
47 wasm_file.read((char*)wasm.data(), wasm.size());
48 wasm_file.close();
49 return wasm;
50 }
51
52 std::vector<char> read_abi( const char* fn ) {
53 std::ifstream abi_file(fn);
54 FC_ASSERT( abi_file.is_open(), "abi file cannot be found" );
55 abi_file.seekg(0, std::ios::end);
56 std::vector<char> abi;
57 int len = abi_file.tellg();
58 FC_ASSERT( len >= 0, "abi file length is -1" );
59 abi.resize(len+1);
60 abi_file.seekg(0, std::ios::beg);
61 abi_file.read(abi.data(), abi.size());
62 abi[abi.size()-1] = '\0';
63 abi_file.close();
64 return abi;
65 }
66
67 namespace {
68 std::string read_gzipped_snapshot( const char* fn ) {
69 std::ifstream file(fn, std::ios_base::in | std::ios_base::binary);
70 bio::filtering_streambuf<bio::input> in;
71
72 in.push(bio::gzip_decompressor());
73 in.push(file);
74
75 std::stringstream decompressed;
76 bio::copy(in, decompressed);
77 return decompressed.str();
78 }
79 }
80
81 std::string read_binary_snapshot( const char* fn ) {
82 return read_gzipped_snapshot(fn);
83 }
84
85 fc::variant read_json_snapshot( const char* fn ) {
86 return fc::json::from_string( read_gzipped_snapshot(fn) );
87 }
88
89 const fc::microseconds base_tester::abi_serializer_max_time{1000*1000}; // 1s for slow test machines
90
91 bool expect_assert_message(const fc::exception& ex, string expected) {
92 BOOST_TEST_MESSAGE("LOG : " << "expected: " << expected << ", actual: " << ex.get_log().at(0).get_message());
93 return (ex.get_log().at(0).get_message().find(expected) != std::string::npos);
94 }
95
98 for( auto& entry : filter ) {
99 auto it = value.find(entry.key());
100 res( it->key(), it->value() );
101 }
102 return res;
103 }
104
106 data.resize( obj.value.size() );
107 memcpy( data.data(), obj.value.data(), obj.value.size() );
108 }
109
112
113 map< builtin_protocol_feature_t, std::optional<digest_type> > visited_builtins;
114
115 std::function<digest_type(builtin_protocol_feature_t)> add_builtins =
116 [&pfs, &visited_builtins, &add_builtins, &custom_subjective_restrictions]
118 auto res = visited_builtins.emplace( codename, std::optional<digest_type>() );
119 if( !res.second ) {
120 SYS_ASSERT( res.first->second, protocol_feature_exception,
121 "invariant failure: cycle found in builtin protocol feature dependencies"
122 );
123 return *res.first->second;
124 }
125
127 [&add_builtins]( builtin_protocol_feature_t d ) {
128 return add_builtins( d );
129 } );
130
131 const auto itr = custom_subjective_restrictions.find(codename);
132 if( itr != custom_subjective_restrictions.end() ) {
133 f.subjective_restrictions = itr->second;
134 }
135
136 const auto& pf = pfs.add_feature( f );
137 res.first->second = pf.feature_digest;
138
139 return pf.feature_digest;
140 };
141
142 for( const auto& p : builtin_protocol_feature_codenames ) {
143 add_builtins( p.first );
144 }
145
146 return pfs;
147 }
148
150 return control->head_block_id() == other.control->head_block_id();
151 }
152
153 void base_tester::init(const setup_policy policy, db_read_mode read_mode, std::optional<uint32_t> genesis_max_inline_action_size, std::optional<uint32_t> config_max_nonprivileged_inline_action_size) {
154 auto def_conf = default_config(tempdir, genesis_max_inline_action_size, config_max_nonprivileged_inline_action_size);
155 def_conf.first.read_mode = read_mode;
156 cfg = def_conf.first;
157
158 open(def_conf.second);
159 execute_setup_policy(policy);
160 }
161
163 cfg = config;
164 open(snapshot);
165 }
166
168 cfg = config;
169 open(genesis);
170 }
171
173 cfg = config;
174 open(default_genesis().compute_chain_id());
175 }
176
178 cfg = config;
179 open(std::move(pfs), snapshot);
180 }
183 cfg = config;
184 open(std::move(pfs), genesis);
185 }
186
188 cfg = config;
189 open(std::move(pfs), default_genesis().compute_chain_id());
190 }
191
193 const auto& pfm = control->get_protocol_feature_manager();
194
195 auto schedule_preactivate_protocol_feature = [&]() {
196 auto preactivate_feature_digest = pfm.get_builtin_digest(builtin_protocol_feature_t::preactivate_feature);
197 FC_ASSERT( preactivate_feature_digest, "PREACTIVATE_FEATURE not found" );
198 schedule_protocol_features_wo_preactivation( { *preactivate_feature_digest } );
199 };
200
201 switch (policy) {
204 break;
205 }
207 schedule_preactivate_protocol_feature();
208 produce_block(); // block production is required to activate protocol feature
209 break;
210 }
212 schedule_preactivate_protocol_feature();
215 break;
216 }
218 schedule_preactivate_protocol_feature();
222 builtin_protocol_feature_t::only_link_to_existing_permission,
223 builtin_protocol_feature_t::replace_deferred,
224 builtin_protocol_feature_t::no_duplicate_deferred_id,
225 builtin_protocol_feature_t::fix_linkauth_restriction,
226 builtin_protocol_feature_t::disallow_empty_producer_schedule,
227 builtin_protocol_feature_t::restrict_action_to_self,
228 builtin_protocol_feature_t::only_bill_first_authorizer,
229 builtin_protocol_feature_t::forward_setcode,
230 builtin_protocol_feature_t::get_sender,
231 builtin_protocol_feature_t::ram_restrictions,
232 builtin_protocol_feature_t::webauthn_key,
233 builtin_protocol_feature_t::wtmsig_block_signatures,
234 builtin_protocol_feature_t::em_key
235 });
238 break;
239 }
240 case setup_policy::full: {
241 schedule_preactivate_protocol_feature();
247 break;
248 }
250 default:
251 break;
252 };
253 }
254
256 control.reset();
257 chain_transactions.clear();
258 }
259
260 void base_tester::open( const snapshot_reader_ptr& snapshot ) {
261 open( make_protocol_feature_set(), snapshot );
262 }
263
264 void base_tester::open( const genesis_state& genesis ) {
265 open( make_protocol_feature_set(), genesis );
266 }
267
268 void base_tester::open( std::optional<chain_id_type> expected_chain_id ) {
269 open( make_protocol_feature_set(), expected_chain_id );
270 }
271
272 template <typename Lambda>
273 void base_tester::open( protocol_feature_set&& pfs, std::optional<chain_id_type> expected_chain_id, Lambda lambda ) {
274 if( !expected_chain_id ) {
276 if( !expected_chain_id ) {
277 if( fc::is_regular_file( cfg.blocks_dir / "blocks.log" ) ) {
278 expected_chain_id = block_log::extract_chain_id( cfg.blocks_dir );
279 } else {
280 expected_chain_id = genesis_state().compute_chain_id();
281 }
282 }
283 }
284
285 control.reset( new controller(cfg, std::move(pfs), *expected_chain_id) );
286 control->add_indices();
287 lambda();
288 chain_transactions.clear();
289 control->accepted_block.connect([this]( const block_state_ptr& block_state ){
291 for( auto receipt : block_state->block->transactions ) {
292 if( std::holds_alternative<packed_transaction>(receipt.trx) ) {
293 auto &pt = std::get<packed_transaction>(receipt.trx);
294 chain_transactions[pt.get_transaction().id()] = std::move(receipt);
295 } else {
296 auto& id = std::get<transaction_id_type>(receipt.trx);
297 chain_transactions[id] = std::move(receipt);
298 }
299 }
300 });
301 }
302
304 const auto& snapshot_chain_id = controller::extract_chain_id( *snapshot );
305 snapshot->return_to_header();
306 open(std::move(pfs), snapshot_chain_id, [&snapshot,&control=this->control]() {
307 control->startup( [](){}, []() { return false; }, snapshot );
308 });
309 }
310
312 open(std::move(pfs), genesis.compute_chain_id(), [&genesis,&control=this->control]() {
313 control->startup( [](){}, []() { return false; }, genesis );
314 });
315 }
316
317 void base_tester::open( protocol_feature_set&& pfs, std::optional<chain_id_type> expected_chain_id ) {
318 open(std::move(pfs), expected_chain_id, [&control=this->control]() {
319 control->startup( [](){}, []() { return false; } );
320 });
321 }
322
323 void base_tester::push_block(signed_block_ptr b) {
324 auto bsf = control->create_block_state_future(b->calculate_id(), b);
325 unapplied_transactions.add_aborted( control->abort_block() );
326 control->push_block( bsf.get(), [this]( const branch_type& forked_branch ) {
327 unapplied_transactions.add_forked( forked_branch );
328 }, [this]( const transaction_id_type& id ) {
329 return unapplied_transactions.get_trx( id );
330 } );
331
332 auto itr = last_produced_block.find(b->producer);
333 if (itr == last_produced_block.end() || b->block_num() > block_header::num_from_id(itr->second)) {
334 last_produced_block[b->producer] = b->calculate_id();
335 }
336 }
337
338 signed_block_ptr base_tester::_produce_block( fc::microseconds skip_time, bool skip_pending_trxs ) {
339 std::vector<transaction_trace_ptr> traces;
340 return _produce_block( skip_time, skip_pending_trxs, false, traces );
341 }
342
343 signed_block_ptr base_tester::_produce_block( fc::microseconds skip_time, bool skip_pending_trxs,
344 bool no_throw, std::vector<transaction_trace_ptr>& traces ) {
345 auto head = control->head_block_state();
346 auto head_time = control->head_block_time();
347 auto next_time = head_time + skip_time;
348
349 if( !control->is_building_block() || control->pending_block_time() != next_time ) {
350 _start_block( next_time );
351 }
352
353 if( !skip_pending_trxs ) {
354 for( auto itr = unapplied_transactions.begin(); itr != unapplied_transactions.end(); ) {
355 auto trace = control->push_transaction( itr->trx_meta, fc::time_point::maximum(), fc::microseconds::maximum(), DEFAULT_BILLED_CPU_TIME_US, true, 0 );
356 traces.emplace_back( trace );
357 if(!no_throw && trace->except) {
358 // this always throws an fc::exception, since the original exception is copied into an fc::exception
359 trace->except->dynamic_rethrow_exception();
360 }
361 itr = unapplied_transactions.erase( itr );
362 }
363
364 vector<transaction_id_type> scheduled_trxs;
365 while ((scheduled_trxs = get_scheduled_transactions()).size() > 0 ) {
366 for( const auto& trx : scheduled_trxs ) {
367 auto trace = control->push_scheduled_transaction( trx, fc::time_point::maximum(), fc::microseconds::maximum(), DEFAULT_BILLED_CPU_TIME_US, true );
368 traces.emplace_back( trace );
369 if( !no_throw && trace->except ) {
370 // this always throws an fc::exception, since the original exception is copied into an fc::exception
371 trace->except->dynamic_rethrow_exception();
372 }
373 }
374 }
375 }
376
377 auto head_block = _finish_block();
378
379 _start_block( next_time + fc::microseconds(config::block_interval_us));
380 return head_block;
381 }
382
383 void base_tester::_start_block(fc::time_point block_time) {
384 auto head_block_number = control->head_block_num();
385 auto producer = control->head_block_state()->get_scheduled_producer(block_time);
386
387 auto last_produced_block_num = control->last_irreversible_block_num();
388 auto itr = last_produced_block.find(producer.producer_name);
389 if (itr != last_produced_block.end()) {
390 last_produced_block_num = std::max(control->last_irreversible_block_num(), block_header::num_from_id(itr->second));
391 }
392
393 unapplied_transactions.add_aborted( control->abort_block() );
394
395 vector<digest_type> feature_to_be_activated;
396 // First add protocol features to be activated WITHOUT preactivation
397 feature_to_be_activated.insert(
398 feature_to_be_activated.end(),
399 protocol_features_to_be_activated_wo_preactivation.begin(),
400 protocol_features_to_be_activated_wo_preactivation.end()
401 );
402 // Then add protocol features to be activated WITH preactivation
403 const auto preactivated_protocol_features = control->get_preactivated_protocol_features();
404 feature_to_be_activated.insert(
405 feature_to_be_activated.end(),
406 preactivated_protocol_features.begin(),
407 preactivated_protocol_features.end()
408 );
409
410 control->start_block( block_time, head_block_number - last_produced_block_num, feature_to_be_activated );
411
412 // Clear the list, if start block finishes successfuly, the protocol features should be assumed to be activated
413 protocol_features_to_be_activated_wo_preactivation.clear();
414 }
415
416 signed_block_ptr base_tester::_finish_block() {
417 FC_ASSERT( control->is_building_block(), "must first start a block before it can be finished" );
418
419 auto producer = control->head_block_state()->get_scheduled_producer( control->pending_block_time() );
420 vector<private_key_type> signing_keys;
421
422 auto default_active_key = get_public_key( producer.producer_name, "active");
423 producer.for_each_key([&](const public_key_type& key){
424 const auto& iter = block_signing_private_keys.find(key);
425 if(iter != block_signing_private_keys.end()) {
426 signing_keys.push_back(iter->second);
427 } else if (key == default_active_key) {
428 signing_keys.emplace_back( get_private_key( producer.producer_name, "active") );
429 }
430 });
431
432 control->finalize_block( [&]( digest_type d ) {
433 std::vector<signature_type> result;
434 result.reserve(signing_keys.size());
435 for (const auto& k: signing_keys)
436 result.emplace_back(k.sign(d));
437
438 return result;
439 } );
440
441 control->commit_block();
442 last_produced_block[control->head_block_state()->header.producer] = control->head_block_state()->id;
443
444 return control->head_block_state()->block;
445 }
446
447 signed_block_ptr base_tester::produce_block( std::vector<transaction_trace_ptr>& traces ) {
448 return _produce_block( fc::milliseconds(config::block_interval_ms), false, true, traces );
449 }
450
451 void base_tester::produce_blocks( uint32_t n, bool empty ) {
452 if( empty ) {
453 for( uint32_t i = 0; i < n; ++i )
454 produce_empty_block();
455 } else {
456 for( uint32_t i = 0; i < n; ++i )
457 produce_block();
458 }
459 }
460
461 vector<transaction_id_type> base_tester::get_scheduled_transactions() const {
462 const auto& idx = control->db().get_index<generated_transaction_multi_index,by_delay>();
463
465
466 auto itr = idx.begin();
467 while( itr != idx.end() && itr->delay_until <= control->pending_block_time() ) {
468 result.emplace_back(itr->trx_id);
469 ++itr;
470 }
471 return result;
472 }
473
474 void base_tester::produce_blocks_until_end_of_round() {
475 uint64_t blocks_per_round;
476 while(true) {
477 blocks_per_round = control->active_producers().producers.size() * config::producer_repetitions;
478 produce_block();
479 if (control->head_block_num() % blocks_per_round == (blocks_per_round - 1)) break;
480 }
481 }
482
483 void base_tester::produce_blocks_for_n_rounds(const uint32_t num_of_rounds) {
484 for(uint32_t i = 0; i < num_of_rounds; i++) {
485 produce_blocks_until_end_of_round();
486 }
487 }
488
489 void base_tester::produce_min_num_of_blocks_to_spend_time_wo_inactive_prod(const fc::microseconds target_elapsed_time) {
490 fc::microseconds elapsed_time;
491 while (elapsed_time < target_elapsed_time) {
492 for(uint32_t i = 0; i < control->head_block_state()->active_schedule.producers.size(); i++) {
493 const auto time_to_skip = fc::milliseconds(config::producer_repetitions * config::block_interval_ms);
494 produce_block(time_to_skip);
495 elapsed_time += time_to_skip;
496 }
497 // if it is more than 24 hours, producer will be marked as inactive
498 const auto time_to_skip = fc::seconds(23 * 60 * 60);
499 produce_block(time_to_skip);
500 elapsed_time += time_to_skip;
501 }
502
503 }
504
505
506 void base_tester::set_transaction_headers( transaction& trx, uint32_t expiration, uint32_t delay_sec ) const {
507 trx.expiration = control->head_block_time() + fc::seconds(expiration);
508 trx.set_reference_block( control->head_block_id() );
509
510 trx.max_net_usage_words = 0; // No limit
511 trx.max_cpu_usage_ms = 0; // No limit
512 trx.delay_sec = delay_sec;
513 }
514
515
516 transaction_trace_ptr base_tester::create_account( account_name a, account_name creator, bool multisig, bool include_code ) {
518 set_transaction_headers(trx);
519
520 authority owner_auth;
521 if( multisig ) {
522 // multisig between account's owner key and creators active permission
523 owner_auth = authority(2, {key_weight{get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}});
524 } else {
525 owner_auth = authority( get_public_key( a, "owner" ) );
526 }
527
528 authority active_auth( get_public_key( a, "active" ) );
529
530 auto sort_permissions = []( authority& auth ) {
531 std::sort( auth.accounts.begin(), auth.accounts.end(),
532 []( const permission_level_weight& lhs, const permission_level_weight& rhs ) {
533 return lhs.permission < rhs.permission;
534 }
535 );
536 };
537
538 if( include_code ) {
539 FC_ASSERT( owner_auth.threshold <= std::numeric_limits<weight_type>::max(), "threshold is too high" );
540 FC_ASSERT( active_auth.threshold <= std::numeric_limits<weight_type>::max(), "threshold is too high" );
541 owner_auth.accounts.push_back( permission_level_weight{ {a, config::sysio_code_name},
542 static_cast<weight_type>(owner_auth.threshold) } );
543 sort_permissions(owner_auth);
544 active_auth.accounts.push_back( permission_level_weight{ {a, config::sysio_code_name},
545 static_cast<weight_type>(active_auth.threshold) } );
546 sort_permissions(active_auth);
547 }
548
549 trx.actions.emplace_back( vector<permission_level>{{creator,config::active_name}},
551 .creator = creator,
552 .name = a,
553 .owner = owner_auth,
554 .active = active_auth,
555 });
556
557 set_transaction_headers(trx);
558 trx.sign( get_private_key( creator, "active" ), control->get_chain_id() );
559 return push_transaction( trx );
560 }
561
562 transaction_trace_ptr base_tester::push_transaction( packed_transaction& trx,
563 fc::time_point deadline,
564 uint32_t billed_cpu_time_us
565 )
566 { try {
567 if( !control->is_building_block() )
568 _start_block(control->head_block_time() + fc::microseconds(config::block_interval_us));
569
570 auto ptrx = std::make_shared<packed_transaction>(trx);
571 auto time_limit = deadline == fc::time_point::maximum() ?
574 auto fut = transaction_metadata::start_recover_keys( ptrx, control->get_thread_pool(), control->get_chain_id(), time_limit, transaction_metadata::trx_type::input );
575 auto r = control->push_transaction( fut.get(), deadline, fc::microseconds::maximum(), billed_cpu_time_us, billed_cpu_time_us > 0, 0 );
576 if( r->except_ptr ) std::rethrow_exception( r->except_ptr );
577 if( r->except ) throw *r->except;
578 return r;
579 } FC_RETHROW_EXCEPTIONS( warn, "transaction_header: ${header}", ("header", transaction_header(trx.get_transaction()) )) }
580
581 transaction_trace_ptr base_tester::push_transaction( signed_transaction& trx,
582 fc::time_point deadline,
583 uint32_t billed_cpu_time_us,
584 bool no_throw
585 )
586 { try {
587 if( !control->is_building_block() )
588 _start_block(control->head_block_time() + fc::microseconds(config::block_interval_us));
590
591 if( fc::raw::pack_size(trx) > 1000 ) {
593 }
594
595 auto time_limit = deadline == fc::time_point::maximum() ?
598 auto ptrx = std::make_shared<packed_transaction>( trx, c );
599 auto fut = transaction_metadata::start_recover_keys( ptrx, control->get_thread_pool(), control->get_chain_id(), time_limit, transaction_metadata::trx_type::input );
600 auto r = control->push_transaction( fut.get(), deadline, fc::microseconds::maximum(), billed_cpu_time_us, billed_cpu_time_us > 0, 0 );
601 if (no_throw) return r;
602 if( r->except_ptr ) std::rethrow_exception( r->except_ptr );
603 if( r->except) throw *r->except;
604 return r;
605 } FC_RETHROW_EXCEPTIONS( warn, "transaction_header: ${header}, billed_cpu_time_us: ${billed}",
606 ("header", transaction_header(trx) ) ("billed", billed_cpu_time_us))
607 }
608
609 typename base_tester::action_result base_tester::push_action(action&& act, uint64_t authorizer) {
611 if (authorizer) {
612 act.authorization = vector<permission_level>{{account_name(authorizer), config::active_name}};
613 }
614 trx.actions.emplace_back(std::move(act));
615 set_transaction_headers(trx);
616 if (authorizer) {
617 trx.sign(get_private_key(account_name(authorizer), "active"), control->get_chain_id());
618 }
619 try {
620 push_transaction(trx);
621 } catch (const fc::exception& ex) {
622 edump((ex.to_detail_string()));
623 return error(ex.top_message()); // top_message() is assumed by many tests; otherwise they fail
624 //return error(ex.to_detail_string());
625 }
626 produce_block();
627 BOOST_REQUIRE_EQUAL(true, chain_has_transaction(trx.id()));
628 return success();
629 }
630
631 transaction_trace_ptr base_tester::push_action( const account_name& code,
632 const action_name& acttype,
633 const account_name& actor,
634 const variant_object& data,
635 uint32_t expiration,
636 uint32_t delay_sec
637 )
638
639 {
641 auths.push_back( permission_level{actor, config::active_name} );
642 return push_action( code, acttype, auths, data, expiration, delay_sec );
643 }
644
645 transaction_trace_ptr base_tester::push_action( const account_name& code,
646 const action_name& acttype,
647 const vector<account_name>& actors,
648 const variant_object& data,
649 uint32_t expiration,
650 uint32_t delay_sec
651 )
652
653 {
655 for (const auto& actor : actors) {
656 auths.push_back( permission_level{actor, config::active_name} );
657 }
658 return push_action( code, acttype, auths, data, expiration, delay_sec );
659 }
660
661 transaction_trace_ptr base_tester::push_action( const account_name& code,
662 const action_name& acttype,
663 const vector<permission_level>& auths,
664 const variant_object& data,
665 uint32_t expiration,
666 uint32_t delay_sec
667 )
668
669 { try {
671 trx.actions.emplace_back( get_action( code, acttype, auths, data ) );
672 set_transaction_headers( trx, expiration, delay_sec );
673 for (const auto& auth : auths) {
674 trx.sign( get_private_key( auth.actor, auth.permission.to_string() ), control->get_chain_id() );
675 }
676
677 return push_transaction( trx );
678 } FC_CAPTURE_AND_RETHROW( (code)(acttype)(auths)(data)(expiration)(delay_sec) ) }
679
680 action base_tester::get_action( account_name code, action_name acttype, vector<permission_level> auths,
681 const variant_object& data )const { try {
682 const auto& acnt = control->get_account(code);
683 auto abi = acnt.get_abi();
685
686 string action_type_name = abis.get_action_type(acttype);
687 FC_ASSERT( action_type_name != string(), "unknown action type ${a}", ("a",acttype) );
688
689
690 action act;
691 act.account = code;
692 act.name = acttype;
693 act.authorization = auths;
695 return act;
697
698 transaction_trace_ptr base_tester::push_reqauth( account_name from, const vector<permission_level>& auths, const vector<private_key_type>& keys ) {
700 ("actions", fc::variants({
702 ("account", name(config::system_account_name))
703 ("name", "reqauth")
704 ("authorization", auths)
706 ("from", from)
707 )
708 })
709 );
710
713 set_transaction_headers(trx);
714 for(auto iter = keys.begin(); iter != keys.end(); iter++)
715 trx.sign( *iter, control->get_chain_id() );
716 return push_transaction( trx );
717 }
718
719
720 transaction_trace_ptr base_tester::push_reqauth(account_name from, string role, bool multi_sig) {
721 if (!multi_sig) {
722 return push_reqauth(from, vector<permission_level>{{from, config::owner_name}},
723 {get_private_key(from, role)});
724 } else {
725 return push_reqauth(from, vector<permission_level>{{from, config::owner_name}},
726 {get_private_key(from, role), get_private_key( config::system_account_name, "active" )} );
727 }
728 }
729
730
731 transaction_trace_ptr base_tester::push_dummy(account_name from, const string& v, uint32_t billed_cpu_time_us) {
732 // use reqauth for a normal action, this could be anything
734 ("actions", fc::variants({
736 ("account", name(config::system_account_name))
737 ("name", "reqauth")
738 ("authorization", fc::variants({
740 ("actor", from)
741 ("permission", name(config::active_name))
742 }))
744 ("from", from)
745 )
746 })
747 )
748 // lets also push a context free action, the multi chain test will then also include a context free action
749 ("context_free_actions", fc::variants({
751 ("account", name(config::null_account_name))
752 ("name", "nonce")
753 ("data", fc::raw::pack(v))
754 })
755 );
756
759 set_transaction_headers(trx);
760
761 trx.sign( get_private_key( from, "active" ), control->get_chain_id() );
762 return push_transaction( trx, fc::time_point::maximum(), billed_cpu_time_us );
763 }
764
765
766 transaction_trace_ptr base_tester::transfer( account_name from, account_name to, string amount, string memo, account_name currency ) {
767 return transfer( from, to, asset::from_string(amount), memo, currency );
768 }
769
770
771 transaction_trace_ptr base_tester::transfer( account_name from, account_name to, asset amount, string memo, account_name currency ) {
773 ("actions", fc::variants({
775 ("account", currency)
776 ("name", "transfer")
777 ("authorization", fc::variants({
779 ("actor", from)
780 ("permission", name(config::active_name))
781 }))
783 ("from", from)
784 ("to", to)
785 ("quantity", amount)
786 ("memo", memo)
787 )
788 })
789 );
790
793 set_transaction_headers(trx);
794
795 trx.sign( get_private_key( from, name(config::active_name).to_string() ), control->get_chain_id() );
796 return push_transaction( trx );
797 }
798
799
800 transaction_trace_ptr base_tester::issue( account_name to, string amount, account_name currency, string memo ) {
802 ("actions", fc::variants({
804 ("account", currency)
805 ("name", "issue")
806 ("authorization", fc::variants({
808 ("actor", currency )
809 ("permission", name(config::active_name))
810 }))
812 ("to", to)
813 ("quantity", amount)
814 ("memo", memo)
815 )
816 })
817 );
818
821 set_transaction_headers(trx);
822
823 trx.sign( get_private_key( currency, name(config::active_name).to_string() ), control->get_chain_id() );
824 return push_transaction( trx );
825 }
826
827
828 void base_tester::link_authority( account_name account, account_name code, permission_name req, action_name type ) {
830
831 trx.actions.emplace_back( vector<permission_level>{{account, config::active_name}},
832 linkauth(account, code, type, req));
833 set_transaction_headers(trx);
834 trx.sign( get_private_key( account, "active" ), control->get_chain_id() );
835
836 push_transaction( trx );
837 }
838
839
840 void base_tester::unlink_authority( account_name account, account_name code, action_name type ) {
842
843 trx.actions.emplace_back( vector<permission_level>{{account, config::active_name}},
844 unlinkauth(account, code, type ));
845 set_transaction_headers(trx);
846 trx.sign( get_private_key( account, "active" ), control->get_chain_id() );
847
848 push_transaction( trx );
849 }
850
851
852 void base_tester::set_authority( account_name account,
853 permission_name perm,
854 authority auth,
855 permission_name parent,
856 const vector<permission_level>& auths,
857 const vector<private_key_type>& keys) { try {
859
860 trx.actions.emplace_back( auths,
862 .account = account,
863 .permission = perm,
864 .parent = parent,
865 .auth = move(auth),
866 });
867
868 set_transaction_headers(trx);
869 for (const auto& key: keys) {
870 trx.sign( key, control->get_chain_id() );
871 }
872
873 push_transaction( trx );
874 } FC_CAPTURE_AND_RETHROW( (account)(perm)(auth)(parent) ) }
875
876
877 void base_tester::set_authority( account_name account,
878 permission_name perm,
879 authority auth,
880 permission_name parent) {
881 set_authority(account, perm, auth, parent, { { account, config::owner_name } }, { get_private_key( account, "owner" ) });
882 }
883
884
885
886 void base_tester::delete_authority( account_name account,
887 permission_name perm,
888 const vector<permission_level>& auths,
889 const vector<private_key_type>& keys ) { try {
891 trx.actions.emplace_back( auths,
892 deleteauth(account, perm) );
893
894 set_transaction_headers(trx);
895 for (const auto& key: keys) {
896 trx.sign( key, control->get_chain_id() );
897 }
898
899 push_transaction( trx );
900 } FC_CAPTURE_AND_RETHROW( (account)(perm) ) }
901
902
903 void base_tester::delete_authority( account_name account,
904 permission_name perm ) {
905 delete_authority(account, perm, { permission_level{ account, config::owner_name } }, { get_private_key( account, "owner" ) });
906 }
907
908
909 void base_tester::set_code( account_name account, const char* wast, const private_key_type* signer ) try {
910 set_code(account, wast_to_wasm(wast), signer);
912
913
914 void base_tester::set_code( account_name account, const vector<uint8_t> wasm, const private_key_type* signer ) try {
916 trx.actions.emplace_back( vector<permission_level>{{account,config::active_name}},
917 setcode{
918 .account = account,
919 .vmtype = 0,
920 .vmversion = 0,
921 .code = bytes(wasm.begin(), wasm.end())
922 });
923
924 set_transaction_headers(trx);
925 if( signer ) {
926 trx.sign( *signer, control->get_chain_id() );
927 } else {
928 trx.sign( get_private_key( account, "active" ), control->get_chain_id() );
929 }
930 push_transaction( trx );
931 } FC_CAPTURE_AND_RETHROW( (account) )
932
933
934 void base_tester::set_abi( account_name account, const char* abi_json, const private_key_type* signer ) {
935 auto abi = fc::json::from_string(abi_json).template as<abi_def>();
936 signed_transaction trx;
937 trx.actions.emplace_back( vector<permission_level>{{account,config::active_name}},
938 setabi{
939 .account = account,
940 .abi = fc::raw::pack(abi)
941 });
942
943 set_transaction_headers(trx);
944 if( signer ) {
945 trx.sign( *signer, control->get_chain_id() );
946 } else {
947 trx.sign( get_private_key( account, "active" ), control->get_chain_id() );
948 }
949 push_transaction( trx );
950 }
951
952
953 bool base_tester::chain_has_transaction( const transaction_id_type& txid ) const {
954 return chain_transactions.count(txid) != 0;
955 }
956
957
958 const transaction_receipt& base_tester::get_transaction_receipt( const transaction_id_type& txid ) const {
959 return chain_transactions.at(txid);
960 }
961
966 asset base_tester::get_currency_balance( const account_name& code,
967 const symbol& asset_symbol,
968 const account_name& account ) const {
969 const auto& db = control->db();
970 const auto* tbl = db.template find<table_id_object, by_code_scope_table>(boost::make_tuple(code, account, "accounts"_n));
971 share_type result = 0;
972
973 // the balance is implied to be 0 if either the table or row does not exist
974 if (tbl) {
975 const auto *obj = db.template find<key_value_object, by_scope_primary>(boost::make_tuple(tbl->id, asset_symbol.to_symbol_code().value));
976 if (obj) {
977 //balance is the first field in the serialization
978 fc::datastream<const char *> ds(obj->value.data(), obj->value.size());
979 fc::raw::unpack(ds, result);
980 }
981 }
982 return asset(result, asset_symbol);
983 }
984
985
986 vector<char> base_tester::get_row_by_account( name code, name scope, name table, const account_name& act ) const {
987 vector<char> data;
988 const auto& db = control->db();
989 const auto* t_id = db.find<chain::table_id_object, chain::by_code_scope_table>( boost::make_tuple( code, scope, table ) );
990 if ( !t_id ) {
991 return data;
992 }
993 //FC_ASSERT( t_id != 0, "object not found" );
994
995 const auto& idx = db.get_index<chain::key_value_index, chain::by_scope_primary>();
996
997 auto itr = idx.lower_bound( boost::make_tuple( t_id->id, act.to_uint64_t() ) );
998 if ( itr == idx.end() || itr->t_id != t_id->id || act.to_uint64_t() != itr->primary_key ) {
999 return data;
1000 }
1001
1002 data.resize( itr->value.size() );
1003 memcpy( data.data(), itr->value.data(), data.size() );
1004 return data;
1005 }
1006
1007
1008 vector<uint8_t> base_tester::to_uint8_vector(const string& s) {
1009 vector<uint8_t> v(s.size());
1010 copy(s.begin(), s.end(), v.begin());
1011 return v;
1012 };
1013
1014
1015 vector<uint8_t> base_tester::to_uint8_vector(uint64_t x) {
1016 vector<uint8_t> v(sizeof(x));
1017 *reinterpret_cast<uint64_t*>(v.data()) = x;
1018 return v;
1019 };
1020
1021
1022 uint64_t base_tester::to_uint64(fc::variant x) {
1025 FC_ASSERT(8 == blob.size());
1026 return *reinterpret_cast<uint64_t*>(blob.data());
1027 }
1028
1029
1030 string base_tester::to_string(fc::variant x) {
1033 string s(v.size(), 0);
1034 copy(v.begin(), v.end(), s.begin());
1035 return s;
1036 }
1037
1038
1039 void base_tester::sync_with(base_tester& other) {
1040 // Already in sync?
1041 if (control->head_block_id() == other.control->head_block_id())
1042 return;
1043 // If other has a longer chain than we do, sync it to us first
1044 if (control->head_block_num() < other.control->head_block_num())
1045 return other.sync_with(*this);
1046
1047 auto sync_dbs = [](base_tester& a, base_tester& b) {
1048 for( uint32_t i = 1; i <= a.control->head_block_num(); ++i ) {
1049
1050 auto block = a.control->fetch_block_by_number(i);
1051 if( block ) { //&& !b.control->is_known_block(block->id()) ) {
1052 auto bsf = b.control->create_block_state_future( block->calculate_id(), block );
1053 b.control->abort_block();
1054 b.control->push_block(bsf.get(), forked_branch_callback{}, trx_meta_cache_lookup{}); //, sysio::chain::validation_steps::created_block);
1055 }
1056 }
1057 };
1058
1059 sync_dbs(*this, other);
1060 sync_dbs(other, *this);
1061 }
1062
1063 void base_tester::set_before_preactivate_bios_contract() {
1064 set_code(config::system_account_name, contracts::before_preactivate_sysio_bios_wasm());
1065 set_abi(config::system_account_name, contracts::before_preactivate_sysio_bios_abi().data());
1066 }
1067
1068 void base_tester::set_before_producer_authority_bios_contract() {
1069 set_code(config::system_account_name, contracts::before_producer_authority_sysio_bios_wasm());
1070 set_abi(config::system_account_name, contracts::before_producer_authority_sysio_bios_abi().data());
1071 }
1072
1073 void base_tester::set_bios_contract() {
1074 set_code(config::system_account_name, contracts::sysio_bios_wasm());
1075 set_abi(config::system_account_name, contracts::sysio_bios_abi().data());
1076 }
1077
1078
1079 vector<producer_authority> base_tester::get_producer_authorities( const vector<account_name>& producer_names )const {
1080 // Create producer schedule
1082 for (auto& producer_name: producer_names) {
1083 schedule.emplace_back(producer_authority{ producer_name, block_signing_authority_v0{1, {{ get_public_key( producer_name, "active" ), 1}} } });
1084 }
1085 return schedule;
1086 }
1087
1088 transaction_trace_ptr base_tester::set_producers(const vector<account_name>& producer_names) {
1089 auto schedule = get_producer_authorities( producer_names );
1090
1091 return set_producer_schedule(schedule);
1092 }
1093
1094 transaction_trace_ptr base_tester::set_producer_schedule(const vector<producer_authority>& schedule ) {
1095 // FC reflection does not create variants that are compatible with ABI 1.1 so we manually translate.
1096 fc::variants schedule_variant;
1097 schedule_variant.reserve(schedule.size());
1098 for( const auto& e: schedule ) {
1099 schedule_variant.emplace_back(e.get_abi_variant());
1100 }
1101
1102 return push_action( config::system_account_name, "setprods"_n, config::system_account_name,
1103 fc::mutable_variant_object()("schedule", schedule_variant));
1104
1105 }
1106
1107 transaction_trace_ptr base_tester::set_producers_legacy(const vector<account_name>& producer_names) {
1108 auto schedule = get_producer_authorities( producer_names );
1109 // down-rank to old version
1110
1111 vector<legacy::producer_key> legacy_keys;
1112 legacy_keys.reserve(schedule.size());
1113 for (const auto &p : schedule) {
1114 std::visit([&legacy_keys, &p](const auto& auth){
1115 legacy_keys.emplace_back(legacy::producer_key{p.producer_name, auth.keys.front().key});
1116 }, p.authority);
1117 }
1118
1119 return push_action( config::system_account_name, "setprods"_n, config::system_account_name,
1120 fc::mutable_variant_object()("schedule", legacy_keys));
1121
1122 }
1123
1124
1125 const table_id_object* base_tester::find_table( name code, name scope, name table ) {
1126 auto tid = control->db().find<table_id_object, by_code_scope_table>(boost::make_tuple(code, scope, table));
1127 return tid;
1128 }
1129
1130 void base_tester::schedule_protocol_features_wo_preactivation(const vector<digest_type> feature_digests) {
1131 protocol_features_to_be_activated_wo_preactivation.insert(
1132 protocol_features_to_be_activated_wo_preactivation.end(),
1133 feature_digests.begin(),
1134 feature_digests.end()
1135 );
1136 }
1137
1138 void base_tester::preactivate_protocol_features(const vector<digest_type> feature_digests) {
1139 for( const auto& feature_digest: feature_digests ) {
1140 push_action( config::system_account_name, "activate"_n, config::system_account_name,
1141 fc::mutable_variant_object()("feature_digest", feature_digest) );
1142 }
1143 }
1144
1145 void base_tester::preactivate_builtin_protocol_features(const std::vector<builtin_protocol_feature_t>& builtin_features) {
1146 const auto& pfs = control->get_protocol_feature_manager().get_protocol_feature_set();
1147
1148 // This behavior is disabled by configurable_wasm_limits
1149 std::vector<digest_type> features;
1150 for(builtin_protocol_feature_t feature : builtin_features ) {
1151 if( auto digest = pfs.get_builtin_digest( feature ) ) {
1152 features.push_back( *digest );
1153 }
1154 }
1155 preactivate_protocol_features(features);
1156 }
1157
1158 void base_tester::preactivate_all_builtin_protocol_features() {
1159 const auto& pfm = control->get_protocol_feature_manager();
1160 const auto& pfs = pfm.get_protocol_feature_set();
1161 const auto current_block_num = control->head_block_num() + (control->is_building_block() ? 1 : 0);
1162 const auto current_block_time = ( control->is_building_block() ? control->pending_block_time()
1163 : control->head_block_time() + fc::milliseconds(config::block_interval_ms) );
1164
1165 set<digest_type> preactivation_set;
1166 vector<digest_type> preactivations;
1167
1168 std::function<void(const digest_type&)> add_digests =
1169 [&pfm, &pfs, current_block_num, current_block_time, &preactivation_set, &preactivations, &add_digests]
1170 ( const digest_type& feature_digest ) {
1171 const auto& pf = pfs.get_protocol_feature( feature_digest );
1172 FC_ASSERT( pf.builtin_feature, "called add_digests on a non-builtin protocol feature" );
1173 if( !pf.enabled || pf.earliest_allowed_activation_time > current_block_time
1174 || pfm.is_builtin_activated( *pf.builtin_feature, current_block_num ) ) return;
1175
1176 auto res = preactivation_set.emplace( feature_digest );
1177 if( !res.second ) return;
1178
1179 for( const auto& dependency : pf.dependencies ) {
1180 add_digests( dependency );
1181 }
1182
1183 preactivations.emplace_back( feature_digest );
1184 };
1185
1186 std::vector<builtin_protocol_feature_t> ordered_builtins;
1187 for( const auto& f : builtin_protocol_feature_codenames ) {
1188 ordered_builtins.push_back( f.first );
1189 }
1190 std::sort( ordered_builtins.begin(), ordered_builtins.end() );
1191 for( const auto& f : ordered_builtins ) {
1192 auto digest = pfs.get_builtin_digest( f);
1193 if( !digest ) continue;
1194 add_digests( *digest );
1195 }
1196
1197 preactivate_protocol_features( preactivations );
1198 }
1199
1200 bool fc_exception_message_is::operator()( const fc::exception& ex ) {
1201 auto message = ex.get_log().at( 0 ).get_message();
1202 bool match = (message == expected);
1203 if( !match ) {
1204 BOOST_TEST_MESSAGE( "LOG: expected: " << expected << ", actual: " << message );
1205 }
1206 return match;
1207 }
1208
1209 bool fc_exception_message_starts_with::operator()( const fc::exception& ex ) {
1210 auto message = ex.get_log().at( 0 ).get_message();
1211 bool match = boost::algorithm::starts_with( message, expected );
1212 if( !match ) {
1213 BOOST_TEST_MESSAGE( "LOG: expected: " << expected << ", actual: " << message );
1214 }
1215 return match;
1216 }
1217
1218 bool fc_assert_exception_message_is::operator()( const fc::assert_exception& ex ) {
1219 auto message = ex.get_log().at( 0 ).get_message();
1220 bool match = false;
1221 auto pos = message.find( ": " );
1222 if( pos != std::string::npos ) {
1223 message = message.substr( pos + 2 );
1224 match = (message == expected);
1225 }
1226 if( !match ) {
1227 BOOST_TEST_MESSAGE( "LOG: expected: " << expected << ", actual: " << message );
1228 }
1229 return match;
1230 }
1231
1232 bool fc_assert_exception_message_starts_with::operator()( const fc::assert_exception& ex ) {
1233 auto message = ex.get_log().at( 0 ).get_message();
1234 bool match = false;
1235 auto pos = message.find( ": " );
1236 if( pos != std::string::npos ) {
1237 message = message.substr( pos + 2 );
1238 match = boost::algorithm::starts_with( message, expected );
1239 }
1240 if( !match ) {
1241 BOOST_TEST_MESSAGE( "LOG: expected: " << expected << ", actual: " << message );
1242 }
1243 return match;
1244 }
1245
1246 bool sysio_assert_message_is::operator()( const sysio_assert_message_exception& ex ) {
1247 auto message = ex.get_log().at( 0 ).get_message();
1248 bool match = (message == expected);
1249 if( !match ) {
1250 BOOST_TEST_MESSAGE( "LOG: expected: " << expected << ", actual: " << message );
1251 }
1252 return match;
1253 }
1254
1255 bool sysio_assert_message_starts_with::operator()( const sysio_assert_message_exception& ex ) {
1256 auto message = ex.get_log().at( 0 ).get_message();
1257 bool match = boost::algorithm::starts_with( message, expected );
1258 if( !match ) {
1259 BOOST_TEST_MESSAGE( "LOG: expected: " << expected << ", actual: " << message );
1260 }
1261 return match;
1262 }
1263
1264 bool sysio_assert_code_is::operator()( const sysio_assert_code_exception& ex ) {
1265 auto message = ex.get_log().at( 0 ).get_message();
1266 bool match = (message == expected);
1267 if( !match ) {
1268 BOOST_TEST_MESSAGE( "LOG: expected: " << expected << ", actual: " << message );
1269 }
1270 return match;
1271 }
1272
1273 const std::string mock::webauthn_private_key::_origin = "mock.webauthn.invalid";
1274 const sha256 mock::webauthn_private_key::_origin_hash = fc::sha256::hash(mock::webauthn_private_key::_origin);
1275} }
1276
1277std::ostream& operator<<( std::ostream& osm, const fc::variant& v ) {
1278 //fc::json::to_stream( osm, v );
1279 osm << fc::json::to_pretty_string( v );
1280 return osm;
1281}
1282
1283std::ostream& operator<<( std::ostream& osm, const fc::variant_object& v ) {
1284 osm << fc::variant(v);
1285 return osm;
1286}
1287
1288std::ostream& operator<<( std::ostream& osm, const fc::variant_object::entry& e ) {
1289 osm << "{ " << e.key() << ": " << e.value() << " }";
1290 return osm;
1291}
const mie::Vuint & p
Definition bn.cpp:27
const mie::Vuint & r
Definition bn.cpp:28
std::string name
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
Used to generate a useful error report when an exception is thrown.
Definition exception.hpp:58
const log_messages & get_log() const
std::string to_detail_string(log_level ll=log_level::all) const
std::string top_message() const
static string to_pretty_string(const variant &v, const yield_function_t &yield, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
Definition json.cpp:775
static variant from_string(const string &utf8_str, const parse_type ptype=parse_type::legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition json.cpp:442
static constexpr microseconds maximum()
Definition time.hpp:14
An order-preserving dictionary of variants.
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
static time_point now()
Definition time.cpp:14
static constexpr time_point maximum()
Definition time.hpp:46
const string & key() const
const variant & value() const
An order-preserving dictionary of variants.
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
static chain_id_type extract_chain_id(const fc::path &data_dir)
static std::optional< chain_id_type > extract_chain_id_from_db(const path &state_dir)
static chain_id_type extract_chain_id(snapshot_reader &snapshot)
static builtin_protocol_feature make_default_builtin_protocol_feature(builtin_protocol_feature_t codename, const std::function< digest_type(builtin_protocol_feature_t dependency)> &handle_dependency)
const protocol_feature & add_feature(const builtin_protocol_feature &f)
symbol_code to_symbol_code() const
Definition symbol.hpp:117
The table_id_object class tracks the mapping of (scope, code, table) to an opaque identifier.
static recover_keys_future start_recover_keys(packed_transaction_ptr trx, boost::asio::io_context &thread_pool, const chain_id_type &chain_id, fc::microseconds time_limit, trx_type t, uint32_t max_variable_sig_size=UINT32_MAX)
static std::pair< controller::config, genesis_state > default_config(const fc::temp_directory &tempdir, std::optional< uint32_t > genesis_max_inline_action_size=std::optional< uint32_t >{}, std::optional< uint32_t > config_max_nonprivileged_inline_action_size=std::optional< uint32_t >{})
Definition tester.hpp:396
static const fc::microseconds abi_serializer_max_time
Definition tester.hpp:153
virtual signed_block_ptr produce_block(fc::microseconds skip_time=fc::milliseconds(config::block_interval_ms))=0
static genesis_state default_genesis()
Definition tester.hpp:388
void execute_setup_policy(const setup_policy policy)
Definition tester.cpp:192
void init(const setup_policy policy=setup_policy::full, db_read_mode read_mode=db_read_mode::SPECULATIVE, std::optional< uint32_t > genesis_max_inline_action_size=std::optional< uint32_t >{}, std::optional< uint32_t > config_max_nonprivileged_inline_action_size=std::optional< uint32_t >{})
Definition tester.cpp:153
void set_before_preactivate_bios_contract()
Definition tester.cpp:1063
bool is_same_chain(base_tester &other)
Definition tester.cpp:149
map< transaction_id_type, transaction_receipt > chain_transactions
Definition tester.hpp:440
controller::config cfg
Definition tester.hpp:439
unique_ptr< controller > control
Definition tester.hpp:436
void preactivate_all_builtin_protocol_features()
Definition tester.cpp:1158
void preactivate_builtin_protocol_features(const std::vector< builtin_protocol_feature_t > &features)
Definition tester.cpp:1145
fc::temp_directory tempdir
Definition tester.hpp:434
void set_before_producer_authority_bios_contract()
Definition tester.cpp:1068
void schedule_protocol_features_wo_preactivation(const vector< digest_type > feature_digests)
Definition tester.cpp:1130
void open(protocol_feature_set &&pfs, std::optional< chain_id_type > expected_chain_id, Lambda lambda)
Definition tester.cpp:273
uint64_t id
Definition code_cache.cpp:0
const struct Ptn tbl[]
#define FC_CAPTURE_AND_RETHROW(...)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception's, std::exceptions, and ... and rethrows them after appending the provided log m...
#define edump(SEQ)
Definition logger.hpp:162
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
size_t pack_size(const T &v)
Definition raw.hpp:671
fc::sha256 digest(const T &value)
Definition digest.hpp:9
fc::string to_string(double)
Definition string.cpp:131
bool is_regular_file(const path &p)
constexpr microseconds milliseconds(int64_t s)
Definition time.hpp:33
void copy(const path &from, const path &to)
std::vector< fc::variant > variants
Definition variant.hpp:173
constexpr microseconds seconds(int64_t s)
Definition time.hpp:32
void from_variant(const fc::variant &v, sysio::chain::chain_id_type &cid)
const std::unordered_map< builtin_protocol_feature_t, builtin_protocol_feature_spec, enum_hash< builtin_protocol_feature_t > > builtin_protocol_feature_codenames
checksum_type digest_type
Definition types.hpp:237
deque< block_state_ptr > branch_type
std::shared_ptr< transaction_trace > transaction_trace_ptr
Definition trace.hpp:20
int64_t share_type
Definition types.hpp:240
sysio::chain::action_name action_name
chainbase::shared_multi_index_container< generated_transaction_object, indexed_by< ordered_unique< tag< by_id >, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, generated_transaction_object::id_type, id)>, ordered_unique< tag< by_trx_id >, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, transaction_id_type, trx_id)>, ordered_unique< tag< by_expiration >, composite_key< generated_transaction_object, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, time_point, expiration), > >, ordered_unique< tag< by_delay >, composite_key< generated_transaction_object, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, time_point, delay_until), > >, ordered_unique< tag< by_sender_id >, composite_key< generated_transaction_object, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, account_name, sender), > > > > generated_transaction_multi_index
std::shared_ptr< signed_block > signed_block_ptr
Definition block.hpp:105
std::shared_ptr< snapshot_reader > snapshot_reader_ptr
Definition snapshot.hpp:294
chainbase::shared_multi_index_container< key_value_object, indexed_by< ordered_unique< tag< by_id >, member< key_value_object, key_value_object::id_type, &key_value_object::id > >, ordered_unique< tag< by_scope_primary >, composite_key< key_value_object, member< key_value_object, table_id, &key_value_object::t_id >, member< key_value_object, uint64_t, &key_value_object::primary_key > >, composite_key_compare< std::less< table_id >, std::less< uint64_t > > > > > key_value_index
std::shared_ptr< block_state > block_state_ptr
uint16_t weight_type
Definition types.hpp:238
fc::crypto::private_key private_key_type
Definition types.hpp:77
name account_name
Definition types.hpp:120
vector< char > bytes
Definition types.hpp:243
std::function< transaction_metadata_ptr(const transaction_id_type &)> trx_meta_cache_lookup
std::function< void(const branch_type &)> forked_branch_callback
std::vector< uint8_t > wast_to_wasm(const std::string &wast)
void copy_row(const chain::key_value_object &obj, vector< char > &data)
Definition tester.cpp:105
std::string read_wast(const char *fn)
Definition tester.cpp:23
fc::variant read_json_snapshot(const char *fn)
Definition tester.cpp:85
std::string read_binary_snapshot(const char *fn)
Definition tester.cpp:81
protocol_feature_set make_protocol_feature_set(const subjective_restriction_map &custom_subjective_restrictions={})
Definition tester.cpp:110
bool expect_assert_message(const fc::exception &ex, string expected)
Definition tester.cpp:91
std::map< builtin_protocol_feature_t, protocol_feature_subjective_restrictions > subjective_restriction_map
Definition tester.hpp:85
fc::variant_object filter_fields(const fc::variant_object &filter, const fc::variant_object &value)
Definition tester.cpp:96
std::vector< uint8_t > read_wasm(const char *fn)
Definition tester.cpp:38
std::vector< char > read_abi(const char *fn)
Definition tester.cpp:52
auto get_private_key(chain::name keyname, std::string role="owner")
#define value
Definition pkcs11.h:157
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
const fc::microseconds abi_serializer_max_time
Definition main.cpp:173
fc::variant push_transaction(signed_transaction &trx, packed_transaction::compression_type compression=packed_transaction::compression_type::none)
Definition main.cpp:325
producer_name(block_signing_key)) FC_REFLECT(producer_set_def
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
std::vector< char > data
Definition variant.hpp:44
static yield_function_t create_yield_function(const fc::microseconds &max_serialization_time)
bytes variant_to_binary(const std::string_view &type, const fc::variant &var, const fc::microseconds &max_serialization_time, bool short_path=false) const
type_name get_action_type(name action) const
static void from_variant(const fc::variant &v, T &o, Resolver resolver, const yield_function_t &yield)
vector< permission_level > authorization
Definition action.hpp:59
static asset from_string(const string &from)
Definition asset.cpp:31
vector< permission_level_weight > accounts
static uint32_t num_from_id(const block_id_type &id)
chain_id_type compute_chain_id() const
Immutable except for fc::from_variant.
Definition name.hpp:43
name(std::string_view str)
Definition name.hpp:56
constexpr uint64_t to_uint64_t() const
Definition name.hpp:61
const transaction & get_transaction() const
const signature_type & sign(const private_key_type &key, const chain_id_type &chain_id)
void set_reference_block(const block_id_type &reference_block)
fc::unsigned_int delay_sec
upper limit on the total CPU time billed for this transaction
uint8_t max_cpu_usage_ms
upper limit on total network bandwidth (in 8 byte words) billed for this transaction
time_point_sec expiration
the time at which a transaction expires
vector< action > actions
transaction_id_type id() const
sysio::chain::asset core_from_string(const std::string &s)
Definition tester.cpp:18
std::ostream & operator<<(std::ostream &osm, const fc::variant &v)
sysio::testing
Definition tester.cpp:1277
void bsf(const Reg &reg, const Operand &op)
CK_ULONG d
char * s
size_t len
memcpy((char *) pInfo->slotDescription, s, l)