diff --git a/src/avalanche/proofbuilder.cpp b/src/avalanche/proofbuilder.cpp index a8612af42..21d2f82d1 100644 --- a/src/avalanche/proofbuilder.cpp +++ b/src/avalanche/proofbuilder.cpp @@ -1,86 +1,86 @@ // Copyright (c) 2020 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include namespace avalanche { SignedStake ProofBuilder::StakeSigner::sign(const StakeCommitment &commitment) { const uint256 h = stake.getHash(commitment); SchnorrSig sig; if (!key.SignSchnorr(h, sig)) { sig.fill(0); } return SignedStake(std::move(stake), std::move(sig)); } bool ProofBuilder::addUTXO(COutPoint utxo, Amount amount, uint32_t height, bool is_coinbase, CKey key) { if (!key.IsValid()) { return false; } return stakes .emplace(Stake(std::move(utxo), amount, height, is_coinbase, key.GetPubKey()), std::move(key)) .second; } -Proof ProofBuilder::build() { +ProofRef ProofBuilder::build() { SchnorrSig proofSignature; const LimitedProofId limitedProofId = getLimitedProofId(); if (!masterKey.SignSchnorr(limitedProofId, proofSignature)) { proofSignature.fill(0); } const ProofId proofid = getProofId(); const StakeCommitment commitment(proofid, expirationTime, masterKey.GetPubKey()); std::vector signedStakes; signedStakes.reserve(stakes.size()); while (!stakes.empty()) { auto handle = stakes.extract(stakes.begin()); signedStakes.push_back(handle.value().sign(commitment)); } - return Proof(sequence, expirationTime, masterKey.GetPubKey(), - std::move(signedStakes), payoutScriptPubKey, - std::move(proofSignature)); + return std::make_shared( + sequence, expirationTime, masterKey.GetPubKey(), + std::move(signedStakes), payoutScriptPubKey, std::move(proofSignature)); } LimitedProofId ProofBuilder::getLimitedProofId() const { CHashWriter ss(SER_GETHASH, 0); ss << sequence; ss << expirationTime; if (!Proof::useLegacy(gArgs)) { ss << payoutScriptPubKey; } WriteCompactSize(ss, stakes.size()); for (const auto &s : stakes) { ss << s.stake; } return LimitedProofId(ss.GetHash()); } ProofId ProofBuilder::getProofId() const { CHashWriter ss(SER_GETHASH, 0); ss << getLimitedProofId(); ss << masterKey.GetPubKey(); return ProofId(ss.GetHash()); } } // namespace avalanche diff --git a/src/avalanche/proofbuilder.h b/src/avalanche/proofbuilder.h index da6ded83b..2f117cde5 100644 --- a/src/avalanche/proofbuilder.h +++ b/src/avalanche/proofbuilder.h @@ -1,61 +1,61 @@ // Copyright (c) 2020 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_AVALANCHE_PROOFBUILDER_H #define BITCOIN_AVALANCHE_PROOFBUILDER_H #include #include #include namespace avalanche { struct TestProofBuilder; class ProofBuilder { uint64_t sequence; int64_t expirationTime; CKey masterKey; CScript payoutScriptPubKey; struct StakeSigner { Stake stake; CKey key; StakeSigner(Stake stake_, CKey key_) : stake(std::move(stake_)), key(std::move(key_)) {} SignedStake sign(const StakeCommitment &commitment); }; struct StakeSignerComparator { bool operator()(const StakeSigner &lhs, const StakeSigner &rhs) const { return lhs.stake.getId() < rhs.stake.getId(); } }; std::set stakes; public: ProofBuilder(uint64_t sequence_, int64_t expirationTime_, CKey masterKey_, const CScript &payoutScriptPubKey_ = CScript()) : sequence(sequence_), expirationTime(expirationTime_), masterKey(std::move(masterKey_)), payoutScriptPubKey(payoutScriptPubKey_) {} [[nodiscard]] bool addUTXO(COutPoint utxo, Amount amount, uint32_t height, bool is_coinbase, CKey key); - Proof build(); + ProofRef build(); private: LimitedProofId getLimitedProofId() const; ProofId getProofId() const; friend struct TestProofBuilder; }; } // namespace avalanche #endif // BITCOIN_AVALANCHE_PROOFBUILDER_H diff --git a/src/avalanche/test/orphanproofpool_tests.cpp b/src/avalanche/test/orphanproofpool_tests.cpp index 44d7389b3..81a28df6b 100644 --- a/src/avalanche/test/orphanproofpool_tests.cpp +++ b/src/avalanche/test/orphanproofpool_tests.cpp @@ -1,163 +1,163 @@ // Copyright (c) 2021 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include using namespace avalanche; BOOST_FIXTURE_TEST_SUITE(orphanproofpool_tests, TestingSetup) /** Make a proof with stakes using random txids */ static ProofRef makeProof(const size_t nStakes) { const Amount v = 5 * COIN; const int height = 1234; ProofBuilder pb(0, 0, CKey::MakeCompressedKey()); for (size_t i = 0; i < nStakes; i++) { TxId txid(GetRandHash()); BOOST_CHECK(pb.addUTXO(COutPoint(txid, 0), v, height, false, CKey::MakeCompressedKey())); } - return std::make_shared(pb.build()); + return pb.build(); } BOOST_AUTO_TEST_CASE(pool_starts_empty) { OrphanProofPool pool{10}; BOOST_CHECK_EQUAL(pool.getNProofs(), 0); BOOST_CHECK_EQUAL(pool.getNStakes(), 0); } BOOST_AUTO_TEST_CASE(fail_to_add_same_proof_twice) { OrphanProofPool pool{10}; auto p = makeProof(1); BOOST_CHECK(!pool.getProof(p->getId())); BOOST_CHECK(pool.addProof(p)); BOOST_CHECK_EQUAL(pool.getNStakes(), 1); BOOST_CHECK_EQUAL(pool.getNProofs(), 1); BOOST_CHECK(pool.getProof(p->getId())); BOOST_CHECK(!pool.addProof(p)); BOOST_CHECK_EQUAL(pool.getNStakes(), 1); BOOST_CHECK_EQUAL(pool.getNProofs(), 1); BOOST_CHECK(pool.getProof(p->getId())); } BOOST_AUTO_TEST_CASE(check_eviction_behavior) { { // Fill the pool OrphanProofPool pool{7}; auto first = makeProof(4); pool.addProof(first); pool.addProof(makeProof(2)); pool.addProof(makeProof(1)); BOOST_CHECK_EQUAL(pool.getNStakes(), 7); BOOST_CHECK_EQUAL(pool.getNProofs(), 3); BOOST_CHECK(pool.getProof(first->getId())); } { OrphanProofPool pool{6}; auto first = makeProof(4); pool.addProof(first); pool.addProof(makeProof(2)); BOOST_CHECK_EQUAL(pool.getNStakes(), 6); BOOST_CHECK_EQUAL(pool.getNProofs(), 2); // The oldest proof has to be dropped pool.addProof(makeProof(1)); BOOST_CHECK_EQUAL(pool.getNStakes(), 3); BOOST_CHECK_EQUAL(pool.getNProofs(), 2); BOOST_CHECK(!pool.getProof(first->getId())); } { OrphanProofPool pool{15}; auto first = makeProof(1); pool.addProof(first); auto second = makeProof(2); pool.addProof(second); pool.addProof(makeProof(4)); pool.addProof(makeProof(8)); BOOST_CHECK_EQUAL(pool.getNStakes(), 15); BOOST_CHECK_EQUAL(pool.getNProofs(), 4); // Multiple proofs are dropped if needed pool.addProof(makeProof(2)); BOOST_CHECK_EQUAL(pool.getNStakes(), 14); BOOST_CHECK_EQUAL(pool.getNProofs(), 3); BOOST_CHECK(!pool.getProof(first->getId())); BOOST_CHECK(!pool.getProof(second->getId())); } } BOOST_AUTO_TEST_CASE(remove_proofs) { OrphanProofPool pool{1337}; std::array aProofIds; // Add 10 proofs for (size_t i = 0; i < 10; i++) { auto p = makeProof(i + 1); aProofIds[i] = p->getId(); BOOST_CHECK(pool.addProof(p)); } BOOST_CHECK_EQUAL(pool.getNProofs(), 10); BOOST_CHECK_EQUAL(pool.getNStakes(), 55); // Remove a proof in the middle BOOST_CHECK(pool.removeProof(aProofIds[5])); BOOST_CHECK_EQUAL(pool.getNProofs(), 9); BOOST_CHECK_EQUAL(pool.getNStakes(), 49); // Remove a proof at the front BOOST_CHECK(pool.removeProof(aProofIds[0])); BOOST_CHECK_EQUAL(pool.getNProofs(), 8); BOOST_CHECK_EQUAL(pool.getNStakes(), 48); // Remove a proof at the back BOOST_CHECK(pool.removeProof(aProofIds[9])); BOOST_CHECK_EQUAL(pool.getNProofs(), 7); BOOST_CHECK_EQUAL(pool.getNStakes(), 38); // Fail to remove a proof that is longer in the pool BOOST_CHECK(!pool.removeProof(aProofIds[5])); BOOST_CHECK_EQUAL(pool.getNProofs(), 7); BOOST_CHECK_EQUAL(pool.getNStakes(), 38); // Fail to remove a proof that was never in the pool auto p = makeProof(11); BOOST_CHECK(!pool.getProof(p->getId())); BOOST_CHECK(!pool.removeProof(p->getId())); BOOST_CHECK_EQUAL(pool.getNProofs(), 7); BOOST_CHECK_EQUAL(pool.getNStakes(), 38); } BOOST_AUTO_TEST_CASE(add_proof_larger_than_pool) { OrphanProofPool pool{AVALANCHE_MAX_PROOF_STAKES - 1}; // Add a couple of small proofs BOOST_CHECK(pool.addProof(makeProof(1))); BOOST_CHECK_EQUAL(pool.getNStakes(), 1); BOOST_CHECK_EQUAL(pool.getNProofs(), 1); BOOST_CHECK(pool.addProof(makeProof(2))); BOOST_CHECK_EQUAL(pool.getNStakes(), 3); BOOST_CHECK_EQUAL(pool.getNProofs(), 2); // Adding a proof larger than the pool causes the pool to be emptied BOOST_CHECK(pool.addProof(makeProof(AVALANCHE_MAX_PROOF_STAKES))); BOOST_CHECK_EQUAL(pool.getNStakes(), 0); BOOST_CHECK_EQUAL(pool.getNProofs(), 0); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/avalanche/test/peermanager_tests.cpp b/src/avalanche/test/peermanager_tests.cpp index d6f3cc14d..476ea824e 100644 --- a/src/avalanche/test/peermanager_tests.cpp +++ b/src/avalanche/test/peermanager_tests.cpp @@ -1,852 +1,852 @@ // Copyright (c) 2020 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include