11#include <test/util/random.h>
12#include <test/util/setup_common.h>
15#include <boost/test/unit_test.hpp>
22struct PeerManagerFixture :
public TestChain100Setup {
23 PeerManagerFixture() {
26 ~PeerManagerFixture() {
32BOOST_FIXTURE_TEST_SUITE(stakecontendercache_tests, TestChain100Setup)
36 std::vector<CScript> manualWinners,
38 std::vector<CScript> winners;
39 size_t expectedSize = manualWinners.size() + avalancheWinners.size();
40 if (expectedSize == 0) {
41 BOOST_CHECK(!cache.getWinners(prevblockhash, winners));
45 BOOST_CHECK(cache.getWinners(prevblockhash, winners));
49 for (
size_t i = 0; i < manualWinners.size(); i++) {
56 std::vector<std::vector<ProofRef>> possibleWinningProofs;
57 for (
auto it = std::next(winners.begin(), manualWinners.size());
58 it != winners.end(); it++) {
59 possibleWinningProofs.push_back(std::vector<ProofRef>());
60 for (
const auto &proof : avalancheWinners) {
61 if (proof->getPayoutScript() == *it) {
62 possibleWinningProofs.back().push_back(proof);
65 BOOST_CHECK(possibleWinningProofs.back().size() > 0);
72 double previousRank = 0;
73 for (
auto possibleWinningProofList : possibleWinningProofs) {
74 double lowestRank = std::numeric_limits<double>::max();
75 for (
const auto &proof : possibleWinningProofList) {
78 if (proofRank < lowestRank) {
79 lowestRank = proofRank;
84 previousRank = lowestRank;
90 const ProofRef &proof,
int expected) {
108 std::vector<int> initialStatuses = {
112 for (uint8_t initialStatus : initialStatuses) {
145 std::vector<CScript> manualWinners = {
150 std::vector<ProofRef> proofs;
151 for (
int i = 0; i < 4; i++) {
159 for (
int i = 0; i < 5; i++) {
168 for (
int p = 0; p < 4; p++) {
195 for (
const auto &proof : proofs) {
207 {proofs[0], proofs[2]});
212 CheckWinners(cache, blockhash, manualWinners, {proofs[0], proofs[2]});
216 std::vector<CScript> moreManualWinners = manualWinners;
217 for (
const auto &proof : proofs) {
218 moreManualWinners.push_back(proof->getPayoutScript());
222 {proofs[0], proofs[2]});
225 {proofs[0], proofs[2]});
229 for (
const auto &proof : proofs) {
233 {proofs[0], proofs[2]});
237 for (
const auto &proof : proofs) {
241 {proofs[0], proofs[2]});
247 {proofs[0], proofs[2]});
253 {proofs[0], proofs[2]});
259 {proofs[0], proofs[1], proofs[2]});
265 {proofs[0], proofs[1]});
267 pindex = pindex->
pprev;
272 for (
const auto &proof : proofs) {
273 manualWinners.push_back(proof->getPayoutScript());
278 for (
int i = 0; i < 5; i++) {
280 {proofs[0], proofs[1]});
281 for (
int p = 0; p < 4; p++) {
284 pindex = pindex->
pprev;
293 std::vector<ProofRef> proofs;
294 for (
int i = 0; i < 10; i++) {
300 std::vector<BlockHash> blockhashes{pindex->
GetBlockHash()};
301 pindex = pindex->
pprev;
302 for (
int i = 0; i < 3; i++) {
304 blockhashes.push_back(blockhash);
305 for (
const auto &proof : proofs) {
309 pindex = pindex->
pprev;
319 for (
int height : {0, 10, 50, 90, 97}) {
365 CheckWinners(cache, blockhashes[2], {CScript()}, proofs);
376 for (
const auto &proof : proofs) {
404 for (
int height : {102, 200, 1000, 1000000}) {
406 for (
size_t i = 1; i < 3; i++) {
407 for (
const auto &proof : proofs) {
408 cache.
add(pindex, proof, InsecureRandBits(2));
413 std::vector<CScript> winners;
416 pindex = pindex->
pprev;
433 for (
int height : {102, 200, 1000, 1000000}) {
447 std::vector<ProofRef> proofs;
448 for (
size_t i = 0; i < 3; i++) {
450 proofs.push_back(proof);
451 const ProofId &proofid = proof->getId();
464 std::vector<BlockHash> blockhashes;
465 for (
size_t i = 0; i < 3; i++) {
467 pindex = pindex->
pprev;
471 for (
size_t i = 0; i < 3; i++) {
473 blockhashes.push_back(blockhash);
476 pindex = pindex->
pprev;
481 for (
int height = 95; height <= 100; height++) {
496 for (
auto &proof : proofs) {
514 for (
auto &proof : proofs) {
526 for (
auto &proof : proofs) {
542 for (
auto &proof : proofs) {
553 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
572BOOST_AUTO_TEST_SUITE_END()
#define Assert(val)
Identity function.
void ForceSetArg(const std::string &strArg, const std::string &strValue)
void ClearForcedArg(const std::string &strArg)
Remove a forced arg setting, used only in testing.
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
BlockHash GetBlockHash() const
int nHeight
height of the entry in the chain. The genesis block has height 0
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CChain m_chain
The current chain of blockheaders we consult and build on.
bool removeNode(NodeId nodeid)
bool isDangling(const ProofId &proofid) const
bool addNode(NodeId nodeid, const ProofId &proofid)
Node API.
bool isBoundToPeer(const ProofId &proofid) const
bool saveRemoteProof(const ProofId &proofid, const NodeId nodeid, const bool present)
bool rejectProof(const ProofId &proofid, RejectionMode mode=RejectionMode::DEFAULT)
void cleanupDanglingProofs(std::unordered_set< ProofRef, SaltedProofHasher > ®isteredProofs)
bool registerProof(const ProofRef &proof, ProofRegistrationState ®istrationState, RegistrationMode mode=RegistrationMode::DEFAULT)
const ProofId & getId() const
Cache to track stake contenders for recent blocks.
bool invalidate(const StakeContenderId &contenderId)
bool accept(const StakeContenderId &contenderId)
Helpers to set avalanche state of a contender.
void cleanup(const int requestedMinHeight)
bool reject(const StakeContenderId &contenderId)
bool setWinners(const CBlockIndex *pindex, const std::vector< CScript > &payoutScripts)
Set proof(s) that should be treated as winners (already finalized).
bool add(const CBlockIndex *pindex, const ProofRef &proof, uint8_t status=StakeContenderStatus::UNKNOWN)
Add a proof to consider in staking rewards pre-consensus.
bool isEmpty() const
For tests.
int getVoteStatus(const StakeContenderId &contenderId, BlockHash &prevblockhashout) const
Get contender acceptance state for avalanche voting.
bool finalize(const StakeContenderId &contenderId)
bool getWinners(const BlockHash &prevblockhash, std::vector< CScript > &payouts) const
Get payout scripts of the winning proofs.
void promoteToBlock(const CBlockIndex *activeTip, PeerManager &pm)
Promote cache entries to a the active chain tip.
static constexpr Amount PROOF_DUST_THRESHOLD
Minimum amount per utxo.
ProofRef buildRandomProof(Chainstate &active_chainstate, uint32_t score, int height, const CKey &masterKey)
constexpr uint32_t MIN_VALID_PROOF_SCORE
Implement std::hash so RCUPtr can be used as a key for maps or sets.
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static void CheckVoteStatus(StakeContenderCache &cache, const BlockHash &prevblockhash, const ProofRef &proof, int expected)
BOOST_FIXTURE_TEST_CASE(promote_tests, PeerManagerFixture)
static void CheckWinners(StakeContenderCache &cache, const BlockHash &prevblockhash, std::vector< CScript > manualWinners, std::vector< ProofRef > avalancheWinners)
BOOST_AUTO_TEST_CASE(vote_status_tests)
A BlockHash is a unqiue identifier for a block.
StakeContenderIds are unique for each block to ensure that the peer polling for their acceptance has ...
double ComputeProofRewardRank(uint32_t proofScore)
To make sure the selection is properly weighted according to the proof score, we normalize the conten...
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.