Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::chain::block_header_state Struct Reference

defines the minimum state necessary to validate transaction headers More...

#include <block_header_state.hpp>

Inheritance diagram for sysio::chain::block_header_state:
Collaboration diagram for sysio::chain::block_header_state:

Public Member Functions

 block_header_state ()=default
 
 block_header_state (detail::block_header_state_common &&base)
 
 block_header_state (legacy::snapshot_block_header_state_v2 &&snapshot)
 
pending_block_header_state next (block_timestamp_type when, uint16_t num_prev_blocks_to_confirm) const
 
block_header_state next (const signed_block_header &h, vector< signature_type > &&additional_signatures, const protocol_feature_set &pfs, const std::function< void(block_timestamp_type, const flat_set< digest_type > &, const vector< digest_type > &)> &validator, bool skip_validate_signee=false) const
 
bool has_pending_producers () const
 
uint32_t calc_dpos_last_irreversible (account_name producer_of_next_block) const
 
producer_authority get_scheduled_producer (block_timestamp_type t) const
 
const block_id_typeprev () const
 
digest_type sig_digest () const
 
void sign (const signer_callback_type &signer)
 
void verify_signee () const
 
const vector< digest_type > & get_new_protocol_feature_activations () const
 

Public Attributes

block_id_type id
 
signed_block_header header
 
detail::schedule_info pending_schedule
 
protocol_feature_activation_set_ptr activated_protocol_features
 
vector< signature_typeadditional_signatures
 
flat_multimap< uint16_t, block_header_extensionheader_exts
 
- Public Attributes inherited from sysio::chain::detail::block_header_state_common
uint32_t block_num = 0
 
uint32_t dpos_proposed_irreversible_blocknum = 0
 
uint32_t dpos_irreversible_blocknum = 0
 
producer_authority_schedule active_schedule
 
incremental_merkle blockroot_merkle
 
flat_map< account_name, uint32_tproducer_to_last_produced
 
flat_map< account_name, uint32_tproducer_to_last_implied_irb
 
block_signing_authority valid_block_signing_authority
 
vector< uint8_tconfirm_count
 

Detailed Description

Definition at line 119 of file block_header_state.hpp.

Constructor & Destructor Documentation

◆ block_header_state() [1/3]

sysio::chain::block_header_state::block_header_state ( )
default

◆ block_header_state() [2/3]

sysio::chain::block_header_state::block_header_state ( detail::block_header_state_common && base)
inlineexplicit

Definition at line 132 of file block_header_state.hpp.

133 :detail::block_header_state_common( std::move(base) )
134 {}

◆ block_header_state() [3/3]

sysio::chain::block_header_state::block_header_state ( legacy::snapshot_block_header_state_v2 && snapshot)
explicit

Definition at line 466 of file block_header_state.cpp.

467 {
468 block_num = snapshot.block_num;
469 dpos_proposed_irreversible_blocknum = snapshot.dpos_proposed_irreversible_blocknum;
470 dpos_irreversible_blocknum = snapshot.dpos_irreversible_blocknum;
471 active_schedule = producer_authority_schedule( snapshot.active_schedule );
472 blockroot_merkle = std::move(snapshot.blockroot_merkle);
473 producer_to_last_produced = std::move(snapshot.producer_to_last_produced);
474 producer_to_last_implied_irb = std::move(snapshot.producer_to_last_implied_irb);
475 valid_block_signing_authority = block_signing_authority_v0{ 1, {{std::move(snapshot.block_signing_key), 1}} };
476 confirm_count = std::move(snapshot.confirm_count);
477 id = std::move(snapshot.id);
478 header = std::move(snapshot.header);
479 pending_schedule.schedule_lib_num = snapshot.pending_schedule.schedule_lib_num;
480 pending_schedule.schedule_hash = std::move(snapshot.pending_schedule.schedule_hash);
481 pending_schedule.schedule = producer_authority_schedule( snapshot.pending_schedule.schedule );
482 activated_protocol_features = std::move(snapshot.activated_protocol_features);
483 }
protocol_feature_activation_set_ptr activated_protocol_features
flat_map< account_name, uint32_t > producer_to_last_implied_irb
flat_map< account_name, uint32_t > producer_to_last_produced
producer_authority_schedule schedule
digest_type schedule_hash
last irr block num

Member Function Documentation

◆ calc_dpos_last_irreversible()

uint32_t sysio::chain::block_header_state::calc_dpos_last_irreversible ( account_name producer_of_next_block) const

2/3 must be greater, so if I go 1/3 into the list sorted from low to high, then 2/3 are greater

Definition at line 24 of file block_header_state.cpp.

24 {
25 vector<uint32_t> blocknums; blocknums.reserve( producer_to_last_implied_irb.size() );
26 for( auto& i : producer_to_last_implied_irb ) {
27 blocknums.push_back( (i.first == producer_of_next_block) ? dpos_proposed_irreversible_blocknum : i.second);
28 }
30
31 if( blocknums.size() == 0 ) return 0;
32
33 std::size_t index = (blocknums.size()-1) / 3;
34 std::nth_element( blocknums.begin(), blocknums.begin() + index, blocknums.end() );
35 return blocknums[ index ];
36 }
Here is the caller graph for this function:

◆ get_new_protocol_feature_activations()

const vector< digest_type > & sysio::chain::block_header_state::get_new_protocol_feature_activations ( ) const

Reference cannot outlive *this. Assumes header_exts is not mutated after instatiation.

Definition at line 457 of file block_header_state.cpp.

457 {
458 static const vector<digest_type> no_activations{};
459
461 return no_activations;
462
463 return std::get<protocol_feature_activation>(header_exts.lower_bound(protocol_feature_activation::extension_id())->second).protocol_features;
464 }
flat_multimap< uint16_t, block_header_extension > header_exts
Here is the call graph for this function:

◆ get_scheduled_producer()

producer_authority sysio::chain::block_header_state::get_scheduled_producer ( block_timestamp_type t) const

Definition at line 18 of file block_header_state.cpp.

18 {
19 auto index = t.slot % (active_schedule.producers.size() * config::producer_repetitions);
20 index /= config::producer_repetitions;
21 return active_schedule.producers[index];
22 }
Here is the caller graph for this function:

◆ has_pending_producers()

bool sysio::chain::block_header_state::has_pending_producers ( ) const
inline

Definition at line 148 of file block_header_state.hpp.

148{ return pending_schedule.schedule.producers.size(); }

◆ next() [1/2]

pending_block_header_state sysio::chain::block_header_state::next ( block_timestamp_type when,
uint16_t num_prev_blocks_to_confirm ) const

grow the confirmed count

confirm the head block too

Definition at line 38 of file block_header_state.cpp.

40 {
41 pending_block_header_state result;
42
43 if( when != block_timestamp_type() ) {
44 SYS_ASSERT( when > header.timestamp, block_validate_exception, "next block must be in the future" );
45 } else {
46 (when = header.timestamp).slot++;
47 }
48
49 auto proauth = get_scheduled_producer(when);
50
51 auto itr = producer_to_last_produced.find( proauth.producer_name );
52 if( itr != producer_to_last_produced.end() ) {
53 SYS_ASSERT( itr->second < (block_num+1) - num_prev_blocks_to_confirm, producer_double_confirm,
54 "producer ${prod} double-confirming known range",
55 ("prod", proauth.producer_name)("num", block_num+1)
56 ("confirmed", num_prev_blocks_to_confirm)("last_produced", itr->second) );
57 }
58
59 result.block_num = block_num + 1;
60 result.previous = id;
61 result.timestamp = when;
62 result.confirmed = num_prev_blocks_to_confirm;
63 result.active_schedule_version = active_schedule.version;
64 result.prev_activated_protocol_features = activated_protocol_features;
65
66 result.valid_block_signing_authority = proauth.authority;
67 result.producer = proauth.producer_name;
68
69 result.blockroot_merkle = blockroot_merkle;
70 result.blockroot_merkle.append( id );
71
73 static_assert(std::numeric_limits<uint8_t>::max() >= (config::max_producers * 2 / 3) + 1, "8bit confirmations may not be able to hold all of the needed confirmations");
74
75 // This uses the previous block active_schedule because thats the "schedule" that signs and therefore confirms _this_ block
76 auto num_active_producers = active_schedule.producers.size();
77 uint32_t required_confs = (uint32_t)(num_active_producers * 2 / 3) + 1;
78
79 if( confirm_count.size() < config::maximum_tracked_dpos_confirmations ) {
80 result.confirm_count.reserve( confirm_count.size() + 1 );
81 result.confirm_count = confirm_count;
82 result.confirm_count.resize( confirm_count.size() + 1 );
83 result.confirm_count.back() = (uint8_t)required_confs;
84 } else {
85 result.confirm_count.resize( confirm_count.size() );
86 memcpy( &result.confirm_count[0], &confirm_count[1], confirm_count.size() - 1 );
87 result.confirm_count.back() = (uint8_t)required_confs;
88 }
89
90 auto new_dpos_proposed_irreversible_blocknum = dpos_proposed_irreversible_blocknum;
91
92 int32_t i = (int32_t)(result.confirm_count.size() - 1);
93 uint32_t blocks_to_confirm = num_prev_blocks_to_confirm + 1;
94 while( i >= 0 && blocks_to_confirm ) {
95 --result.confirm_count[i];
96 //idump((confirm_count[i]));
97 if( result.confirm_count[i] == 0 )
98 {
99 uint32_t block_num_for_i = result.block_num - (uint32_t)(result.confirm_count.size() - 1 - i);
100 new_dpos_proposed_irreversible_blocknum = block_num_for_i;
101 //idump((dpos2_lib)(block_num)(dpos_irreversible_blocknum));
102
103 if (i == static_cast<int32_t>(result.confirm_count.size() - 1)) {
104 result.confirm_count.resize(0);
105 } else {
106 memmove( &result.confirm_count[0], &result.confirm_count[i + 1], result.confirm_count.size() - i - 1);
107 result.confirm_count.resize( result.confirm_count.size() - i - 1 );
108 }
109
110 break;
111 }
112 --i;
113 --blocks_to_confirm;
114 }
115
116 result.dpos_proposed_irreversible_blocknum = new_dpos_proposed_irreversible_blocknum;
117 result.dpos_irreversible_blocknum = calc_dpos_last_irreversible( proauth.producer_name );
118
119 result.prev_pending_schedule = pending_schedule;
120
122 result.dpos_irreversible_blocknum >= pending_schedule.schedule_lib_num )
123 {
124 result.active_schedule = pending_schedule.schedule;
125
126 flat_map<account_name,uint32_t> new_producer_to_last_produced;
127
128 for( const auto& pro : result.active_schedule.producers ) {
129 if( pro.producer_name == proauth.producer_name ) {
130 new_producer_to_last_produced[pro.producer_name] = result.block_num;
131 } else {
132 auto existing = producer_to_last_produced.find( pro.producer_name );
133 if( existing != producer_to_last_produced.end() ) {
134 new_producer_to_last_produced[pro.producer_name] = existing->second;
135 } else {
136 new_producer_to_last_produced[pro.producer_name] = result.dpos_irreversible_blocknum;
137 }
138 }
139 }
140 new_producer_to_last_produced[proauth.producer_name] = result.block_num;
141
142 result.producer_to_last_produced = std::move( new_producer_to_last_produced );
143
144 flat_map<account_name,uint32_t> new_producer_to_last_implied_irb;
145
146 for( const auto& pro : result.active_schedule.producers ) {
147 if( pro.producer_name == proauth.producer_name ) {
148 new_producer_to_last_implied_irb[pro.producer_name] = dpos_proposed_irreversible_blocknum;
149 } else {
150 auto existing = producer_to_last_implied_irb.find( pro.producer_name );
151 if( existing != producer_to_last_implied_irb.end() ) {
152 new_producer_to_last_implied_irb[pro.producer_name] = existing->second;
153 } else {
154 new_producer_to_last_implied_irb[pro.producer_name] = result.dpos_irreversible_blocknum;
155 }
156 }
157 }
158
159 result.producer_to_last_implied_irb = std::move( new_producer_to_last_implied_irb );
160
161 result.was_pending_promoted = true;
162 } else {
163 result.active_schedule = active_schedule;
164 result.producer_to_last_produced = producer_to_last_produced;
165 result.producer_to_last_produced[proauth.producer_name] = result.block_num;
166 result.producer_to_last_implied_irb = producer_to_last_implied_irb;
167 result.producer_to_last_implied_irb[proauth.producer_name] = dpos_proposed_irreversible_blocknum;
168 }
169
170 return result;
171 }
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
block_timestamp< config::block_interval_ms, config::block_timestamp_epoch > block_timestamp_type
key Invalid authority Invalid transaction Invalid block ID Invalid packed transaction Invalid chain ID Invalid symbol Signature type is not a currently activated type Block can not be found block_validate_exception
unsigned int uint32_t
Definition stdint.h:126
signed int int32_t
Definition stdint.h:123
unsigned char uint8_t
Definition stdint.h:124
producer_authority get_scheduled_producer(block_timestamp_type t) const
uint32_t calc_dpos_last_irreversible(account_name producer_of_next_block) const
block_timestamp_type timestamp
uint32_t version
sequentially incrementing version number
yubihsm_pkcs11_slot * slot
memcpy((char *) pInfo->slotDescription, s, l)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ next() [2/2]

block_header_state sysio::chain::block_header_state::next ( const signed_block_header & h,
vector< signature_type > && _additional_signatures,
const protocol_feature_set & pfs,
const std::function< void(block_timestamp_type, const flat_set< digest_type > &, const vector< digest_type > &)> & validator,
bool skip_validate_signee = false ) const

Transitions the current header state into the next header state given the supplied signed block header.

Given a signed block header, generate the expected template based upon the header time, then validate that the provided header matches the template.

If the header specifies new_producers then apply them accordingly.

Definition at line 391 of file block_header_state.cpp.

399 {
400 return next( h.timestamp, h.confirmed ).finish_next( h, std::move(_additional_signatures), pfs, validator, skip_validate_signee );
401 }
pending_block_header_state next(block_timestamp_type when, uint16_t num_prev_blocks_to_confirm) const
block_header_state finish_next(const signed_block_header &h, vector< signature_type > &&additional_signatures, const protocol_feature_set &pfs, const std::function< void(block_timestamp_type, const flat_set< digest_type > &, const vector< digest_type > &)> &validator, bool skip_validate_signee=false) &&
Here is the call graph for this function:

◆ prev()

const block_id_type & sysio::chain::block_header_state::prev ( ) const
inline

Definition at line 152 of file block_header_state.hpp.

152{ return header.previous; }

◆ sig_digest()

digest_type sysio::chain::block_header_state::sig_digest ( ) const

Definition at line 403 of file block_header_state.cpp.

403 {
404 auto header_bmroot = digest_type::hash( std::make_pair( header.digest(), blockroot_merkle.get_root() ) );
405 return digest_type::hash( std::make_pair(header_bmroot, pending_schedule.schedule_hash) );
406 }
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
digest_type digest() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sign()

void sysio::chain::block_header_state::sign ( const signer_callback_type & signer)

Definition at line 408 of file block_header_state.cpp.

408 {
409 auto d = sig_digest();
410 auto sigs = signer( d );
411
412 SYS_ASSERT(!sigs.empty(), no_block_signatures, "Signer returned no signatures");
413 header.producer_signature = sigs.back();
414 sigs.pop_back();
415
416 additional_signatures = std::move(sigs);
417
419 }
vector< signature_type > additional_signatures
CK_ULONG d
Here is the call graph for this function:

◆ verify_signee()

void sysio::chain::block_header_state::verify_signee ( ) const

Definition at line 421 of file block_header_state.cpp.

421 {
422
423 auto num_keys_in_authority = std::visit([](const auto &a){ return a.keys.size(); }, valid_block_signing_authority);
424 SYS_ASSERT(1 + additional_signatures.size() <= num_keys_in_authority, wrong_signing_key,
425 "number of block signatures (${num_block_signatures}) exceeds number of keys in block signing authority (${num_keys})",
426 ("num_block_signatures", 1 + additional_signatures.size())
427 ("num_keys", num_keys_in_authority)
428 ("authority", valid_block_signing_authority)
429 );
430
431 std::set<public_key_type> keys;
432 auto digest = sig_digest();
434
435 for (const auto& s: additional_signatures) {
436 auto res = keys.emplace(s, digest, true);
437 SYS_ASSERT(res.second, wrong_signing_key, "block signed by same key twice", ("key", *res.first));
438 }
439
440 bool is_satisfied = false;
441 size_t relevant_sig_count = 0;
442
443 std::tie(is_satisfied, relevant_sig_count) = producer_authority::keys_satisfy_and_relevant(keys, valid_block_signing_authority);
444
445 SYS_ASSERT(relevant_sig_count == keys.size(), wrong_signing_key,
446 "block signed by unexpected key",
447 ("signing_keys", keys)("authority", valid_block_signing_authority));
448
449 SYS_ASSERT(is_satisfied, wrong_signing_key,
450 "block signatures do not satisfy the block signing authority",
451 ("signing_keys", keys)("authority", valid_block_signing_authority));
452 }
fc::sha256 digest(const T &value)
Definition digest.hpp:9
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
static std::pair< bool, size_t > keys_satisfy_and_relevant(const std::set< public_key_type > &keys, const block_signing_authority &authority)
char * s
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ activated_protocol_features

protocol_feature_activation_set_ptr sysio::chain::block_header_state::activated_protocol_features

Definition at line 123 of file block_header_state.hpp.

◆ additional_signatures

vector<signature_type> sysio::chain::block_header_state::additional_signatures

Definition at line 124 of file block_header_state.hpp.

◆ header

signed_block_header sysio::chain::block_header_state::header

Definition at line 121 of file block_header_state.hpp.

◆ header_exts

flat_multimap<uint16_t, block_header_extension> sysio::chain::block_header_state::header_exts

this data is redundant with the data stored in header, but it acts as a cache that avoids duplication of work

Definition at line 128 of file block_header_state.hpp.

◆ id

block_id_type sysio::chain::block_header_state::id

Definition at line 120 of file block_header_state.hpp.

◆ pending_schedule

detail::schedule_info sysio::chain::block_header_state::pending_schedule

Definition at line 122 of file block_header_state.hpp.


The documentation for this struct was generated from the following files: