db_block.cpp: Fix tapos rollover logic
This commit is contained in:
parent
f46758e97c
commit
5f5e761ca8
1 changed files with 55 additions and 3 deletions
|
|
@ -468,10 +468,62 @@ processed_transaction database::_apply_transaction( const signed_transaction& tr
|
||||||
//Check the TaPoS reference and expiration time
|
//Check the TaPoS reference and expiration time
|
||||||
//Remember that the TaPoS block number is abbreviated; it contains only the lower 16 bits.
|
//Remember that the TaPoS block number is abbreviated; it contains only the lower 16 bits.
|
||||||
//Lookup TaPoS block summary by block number (remember block summary instances are the block numbers)
|
//Lookup TaPoS block summary by block number (remember block summary instances are the block numbers)
|
||||||
|
|
||||||
|
// Let N = head_block_num(), a = N & 0xFFFF, and r = trx.ref_block_num
|
||||||
|
//
|
||||||
|
// We want to solve for the largest block height x such that
|
||||||
|
// these two conditions hold:
|
||||||
|
//
|
||||||
|
// (a) 0x10000 divides x-r
|
||||||
|
// (b) x <= N
|
||||||
|
//
|
||||||
|
// Let us define:
|
||||||
|
//
|
||||||
|
// x1 = N-a+r
|
||||||
|
// x0 = x1-2^16
|
||||||
|
// x2 = x1+2^16
|
||||||
|
//
|
||||||
|
// It is clear that x0, x1, x2 are consecutive solutions to (a).
|
||||||
|
//
|
||||||
|
// Since r < 2^16 and a < 2^16, it follows that
|
||||||
|
// -2^16 < r-a < 2^16. From this we know that x0 < N and x2 > N.
|
||||||
|
//
|
||||||
|
// Case (1): x1 <= N. In this case, x1 must be the greatest
|
||||||
|
// integer that satisfies (a) and (b); for x2, the next
|
||||||
|
// largest integer that satisfies (a), does not satisfy (b).
|
||||||
|
//
|
||||||
|
// Case (2): x1 > N. In this case, x0 must be the greatest
|
||||||
|
// integer that satisfies (a) and (b); for x1, the next
|
||||||
|
// largest integer that satisfies (a), does not satisfy (b).
|
||||||
|
//
|
||||||
|
int64_t N = head_block_num();
|
||||||
|
int64_t a = N & 0xFFFF;
|
||||||
|
int64_t r = trx.ref_block_num;
|
||||||
|
|
||||||
|
int64_t x1 = N-a+r;
|
||||||
|
int64_t x0 = x1 - 0x10000;
|
||||||
|
int64_t x2 = x1 + 0x10000;
|
||||||
|
|
||||||
|
assert( x0 < N );
|
||||||
|
assert( x1 >= 0 );
|
||||||
|
assert( x2 > N );
|
||||||
|
|
||||||
|
uint32_t ref_block_height;
|
||||||
|
if( x1 <= N )
|
||||||
|
{
|
||||||
|
FC_ASSERT( x1 > 0 );
|
||||||
|
ref_block_height = uint32_t( x1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ref_block_height = uint32_t( x0 );
|
||||||
|
}
|
||||||
|
|
||||||
const block_summary_object& tapos_block_summary
|
const block_summary_object& tapos_block_summary
|
||||||
= static_cast<const block_summary_object&>(get_index<block_summary_object>()
|
= static_cast<const block_summary_object&>(
|
||||||
.get(block_summary_id_type((head_block_num() & ~0xffff)
|
get_index<block_summary_object>()
|
||||||
+ trx.ref_block_num)));
|
.get(block_summary_id_type(ref_block_height))
|
||||||
|
);
|
||||||
|
|
||||||
//This is the signature check for transactions with relative expiration.
|
//This is the signature check for transactions with relative expiration.
|
||||||
if( !(skip & skip_transaction_signatures) )
|
if( !(skip & skip_transaction_signatures) )
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue