27 namespace graphene {
namespace chain {
40 auto prev = _head->prev.lock();
41 FC_ASSERT( prev,
"popping block would leave head block null" );
47 auto item = std::make_shared<fork_item>(std::move(b));
58 auto item = std::make_shared<fork_item>(b);
62 catch (
const unlinkable_block_exception& e )
64 wlog(
"Pushing block to fork database that failed to link: ${id}, ${num}", (
"id",b.
id())(
"num",b.
block_num()) );
65 wlog(
"Head: ${num}, ${id}", (
"num",_head->data.block_num())(
"id",_head->data.id()) );
71 void fork_database::_push_block(
const item_ptr& item)
75 FC_ASSERT( item->num > std::max<int64_t>( 0, int64_t(_head->num) - (_max_size) ),
76 "attempting to push a block that is too old",
77 (
"item->num",item->num)(
"head",_head->num)(
"max_size",_max_size));
82 auto&
index = _index.get<block_id>();
83 auto itr =
index.find(item->previous_id());
84 GRAPHENE_ASSERT(itr !=
index.end(), unlinkable_block_exception,
"block does not link to known chain");
89 if( !_head ) _head = item;
90 else if( item->num > _head->num )
93 uint32_t min_num = _head->num - std::min( _max_size, _head->num );
94 auto& num_idx = _index.get<block_num>();
95 while( !num_idx.empty() && (*num_idx.begin())->num < min_num )
96 num_idx.erase( num_idx.begin() );
105 auto& by_num_idx = _index.get<block_num>();
106 auto itr = by_num_idx.begin();
107 while( itr != by_num_idx.end() )
109 if( (*itr)->num < std::max(int64_t(0),int64_t(_head->num) - _max_size) )
110 by_num_idx.erase(itr);
113 itr = by_num_idx.begin();
119 auto&
index = _index.get<block_id>();
121 return itr !=
index.end();
126 auto&
index = _index.get<block_id>();
128 if( itr !=
index.end() )
135 vector<item_ptr> result;
136 auto itr = _index.get<block_num>().find(num);
137 while( itr != _index.get<block_num>().end() )
139 if( (*itr)->num == num )
140 result.push_back( *itr );
148 pair<fork_database::branch_type,fork_database::branch_type>
153 pair<branch_type,branch_type> result;
154 auto first_branch_itr = _index.get<block_id>().find(
first);
155 FC_ASSERT(first_branch_itr != _index.get<block_id>().end());
156 auto first_branch = *first_branch_itr;
158 auto second_branch_itr = _index.get<block_id>().find(second);
159 FC_ASSERT(second_branch_itr != _index.get<block_id>().end());
160 auto second_branch = *second_branch_itr;
163 while( first_branch->data.block_num() > second_branch->data.block_num() )
165 result.first.push_back(first_branch);
166 first_branch = first_branch->prev.lock();
169 while( second_branch->data.block_num() > first_branch->data.block_num() )
171 result.second.push_back( second_branch );
172 second_branch = second_branch->prev.lock();
175 while( first_branch->data.previous != second_branch->data.previous )
177 result.first.push_back(first_branch);
178 result.second.push_back(second_branch);
179 first_branch = first_branch->prev.lock();
181 second_branch = second_branch->prev.lock();
184 if( first_branch && second_branch )
186 result.first.push_back(first_branch);
187 result.second.push_back(second_branch);
199 _index.get<block_id>().erase(
id);
201 if( _head && _head->id ==
id )