Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F10615045
pow.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Subscribers
None
pow.cpp
View Options
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include
"pow.h"
#include
"arith_uint256.h"
#include
"chain.h"
#include
"primitives/block.h"
#include
"uint256.h"
#include
"util.h"
unsigned
int
GetNextWorkRequired
(
const
CBlockIndex
*
pindexLast
,
const
CBlockHeader
*
pblock
,
const
Consensus
::
Params
&
params
)
{
unsigned
int
nProofOfWorkLimit
=
UintToArith256
(
params
.
powLimit
).
GetCompact
();
// Genesis block
if
(
pindexLast
==
NULL
)
return
nProofOfWorkLimit
;
// Only change once per difficulty adjustment interval
if
((
pindexLast
->
nHeight
+
1
)
%
params
.
DifficultyAdjustmentInterval
()
!=
0
)
{
if
(
params
.
fPowAllowMinDifficultyBlocks
)
{
// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
if
(
pblock
->
GetBlockTime
()
>
pindexLast
->
GetBlockTime
()
+
params
.
nPowTargetSpacing
*
2
)
return
nProofOfWorkLimit
;
else
{
// Return the last non-special-min-difficulty-rules-block
const
CBlockIndex
*
pindex
=
pindexLast
;
while
(
pindex
->
pprev
&&
pindex
->
nHeight
%
params
.
DifficultyAdjustmentInterval
()
!=
0
&&
pindex
->
nBits
==
nProofOfWorkLimit
)
pindex
=
pindex
->
pprev
;
return
pindex
->
nBits
;
}
}
return
pindexLast
->
nBits
;
}
// Go back by what we want to be 14 days worth of blocks
int
nHeightFirst
=
pindexLast
->
nHeight
-
(
params
.
DifficultyAdjustmentInterval
()
-1
);
assert
(
nHeightFirst
>=
0
);
const
CBlockIndex
*
pindexFirst
=
pindexLast
->
GetAncestor
(
nHeightFirst
);
assert
(
pindexFirst
);
return
CalculateNextWorkRequired
(
pindexLast
,
pindexFirst
->
GetBlockTime
(),
params
);
}
unsigned
int
CalculateNextWorkRequired
(
const
CBlockIndex
*
pindexLast
,
int64_t
nFirstBlockTime
,
const
Consensus
::
Params
&
params
)
{
if
(
params
.
fPowNoRetargeting
)
return
pindexLast
->
nBits
;
// Limit adjustment step
int64_t
nActualTimespan
=
pindexLast
->
GetBlockTime
()
-
nFirstBlockTime
;
LogPrintf
(
" nActualTimespan = %d before bounds
\n
"
,
nActualTimespan
);
if
(
nActualTimespan
<
params
.
nPowTargetTimespan
/
4
)
nActualTimespan
=
params
.
nPowTargetTimespan
/
4
;
if
(
nActualTimespan
>
params
.
nPowTargetTimespan
*
4
)
nActualTimespan
=
params
.
nPowTargetTimespan
*
4
;
// Retarget
const
arith_uint256
bnPowLimit
=
UintToArith256
(
params
.
powLimit
);
arith_uint256
bnNew
;
arith_uint256
bnOld
;
bnNew
.
SetCompact
(
pindexLast
->
nBits
);
bnOld
=
bnNew
;
bnNew
*=
nActualTimespan
;
bnNew
/=
params
.
nPowTargetTimespan
;
if
(
bnNew
>
bnPowLimit
)
bnNew
=
bnPowLimit
;
/// debug print
LogPrintf
(
"GetNextWorkRequired RETARGET
\n
"
);
LogPrintf
(
"params.nPowTargetTimespan = %d nActualTimespan = %d
\n
"
,
params
.
nPowTargetTimespan
,
nActualTimespan
);
LogPrintf
(
"Before: %08x %s
\n
"
,
pindexLast
->
nBits
,
bnOld
.
ToString
());
LogPrintf
(
"After: %08x %s
\n
"
,
bnNew
.
GetCompact
(),
bnNew
.
ToString
());
return
bnNew
.
GetCompact
();
}
bool
CheckProofOfWork
(
uint256
hash
,
unsigned
int
nBits
,
const
Consensus
::
Params
&
params
)
{
bool
fNegative
;
bool
fOverflow
;
arith_uint256
bnTarget
;
bnTarget
.
SetCompact
(
nBits
,
&
fNegative
,
&
fOverflow
);
// Check range
if
(
fNegative
||
bnTarget
==
0
||
fOverflow
||
bnTarget
>
UintToArith256
(
params
.
powLimit
))
return
error
(
"CheckProofOfWork(): nBits below minimum work"
);
// Check proof of work matches claimed amount
if
(
UintToArith256
(
hash
)
>
bnTarget
)
return
error
(
"CheckProofOfWork(): hash doesn't match nBits"
);
return
true
;
}
arith_uint256
GetBlockProof
(
const
CBlockIndex
&
block
)
{
arith_uint256
bnTarget
;
bool
fNegative
;
bool
fOverflow
;
bnTarget
.
SetCompact
(
block
.
nBits
,
&
fNegative
,
&
fOverflow
);
if
(
fNegative
||
fOverflow
||
bnTarget
==
0
)
return
0
;
// We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
// as it's too large for a arith_uint256. However, as 2**256 is at least as large
// as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
// or ~bnTarget / (nTarget+1) + 1.
return
(
~
bnTarget
/
(
bnTarget
+
1
))
+
1
;
}
int64_t
GetBlockProofEquivalentTime
(
const
CBlockIndex
&
to
,
const
CBlockIndex
&
from
,
const
CBlockIndex
&
tip
,
const
Consensus
::
Params
&
params
)
{
arith_uint256
r
;
int
sign
=
1
;
if
(
to
.
nChainWork
>
from
.
nChainWork
)
{
r
=
to
.
nChainWork
-
from
.
nChainWork
;
}
else
{
r
=
from
.
nChainWork
-
to
.
nChainWork
;
sign
=
-1
;
}
r
=
r
*
arith_uint256
(
params
.
nPowTargetSpacing
)
/
GetBlockProof
(
tip
);
if
(
r
.
bits
()
>
63
)
{
return
sign
*
std
::
numeric_limits
<
int64_t
>::
max
();
}
return
sign
*
r
.
GetLow64
();
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Nov 23, 09:55 (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4519663
Default Alt Text
pow.cpp (4 KB)
Attached To
rSTAGING Bitcoin ABC staging
Event Timeline
Log In to Comment