diff --git a/src/avalanche/proofbuilder.cpp b/src/avalanche/proofbuilder.cpp index 9227ab16d..6e618e579 100644 --- a/src/avalanche/proofbuilder.cpp +++ b/src/avalanche/proofbuilder.cpp @@ -1,73 +1,67 @@ // 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 namespace avalanche { SignedStake ProofBuilder::StakeSigner::sign(const ProofId &proofid) { const uint256 h = stake.getHash(proofid); 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; } - stakes.emplace_back( - Stake(std::move(utxo), amount, height, is_coinbase, key.GetPubKey()), - std::move(key)); - return true; + return stakes + .emplace(Stake(std::move(utxo), amount, height, is_coinbase, + key.GetPubKey()), + std::move(key)) + .second; } Proof ProofBuilder::build() { const ProofId proofid = getProofId(); std::vector signedStakes; signedStakes.reserve(stakes.size()); - for (auto &s : stakes) { - signedStakes.push_back(s.sign(proofid)); + while (!stakes.empty()) { + auto handle = stakes.extract(stakes.begin()); + signedStakes.push_back(handle.value().sign(proofid)); } - stakes.clear(); return Proof(sequence, expirationTime, std::move(master), std::move(signedStakes)); } -ProofId ProofBuilder::getProofId() { +ProofId ProofBuilder::getProofId() const { CHashWriter ss(SER_GETHASH, 0); ss << sequence; ss << expirationTime; - // TODO This can be avoided by using a sorted container instead of a vector - // for the stakes. - std::sort(stakes.begin(), stakes.end(), - [](const StakeSigner &lhs, const StakeSigner &rhs) { - return lhs.stake.getId() < rhs.stake.getId(); - }); - WriteCompactSize(ss, stakes.size()); for (const auto &s : stakes) { ss << s.stake; } CHashWriter ss2(SER_GETHASH, 0); ss2 << ss.GetHash(); ss2 << master; return ProofId(ss2.GetHash()); } } // namespace avalanche diff --git a/src/avalanche/proofbuilder.h b/src/avalanche/proofbuilder.h index 777fe4454..4a56ab4ec 100644 --- a/src/avalanche/proofbuilder.h +++ b/src/avalanche/proofbuilder.h @@ -1,52 +1,57 @@ // 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; CPubKey master; struct StakeSigner { Stake stake; CKey key; StakeSigner(Stake stake_, CKey key_) : stake(std::move(stake_)), key(std::move(key_)) {} SignedStake sign(const ProofId &proofid); }; - std::vector stakes; + 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_, CPubKey master_) : sequence(sequence_), expirationTime(expirationTime_), master(std::move(master_)) {} bool addUTXO(COutPoint utxo, Amount amount, uint32_t height, bool is_coinbase, CKey key); Proof build(); private: - ProofId getProofId(); + ProofId getProofId() const; friend struct TestProofBuilder; }; } // namespace avalanche #endif // BITCOIN_AVALANCHE_PROOFBUILDER_H diff --git a/src/avalanche/test/peermanager_tests.cpp b/src/avalanche/test/peermanager_tests.cpp index 1be7499ee..d8affb7bb 100644 --- a/src/avalanche/test/peermanager_tests.cpp +++ b/src/avalanche/test/peermanager_tests.cpp @@ -1,791 +1,797 @@ // 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