Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/proofbuilder.cpp
Show All 19 Lines | |||||
} | } | ||||
bool ProofBuilder::addUTXO(COutPoint utxo, Amount amount, uint32_t height, | bool ProofBuilder::addUTXO(COutPoint utxo, Amount amount, uint32_t height, | ||||
bool is_coinbase, CKey key) { | bool is_coinbase, CKey key) { | ||||
if (!key.IsValid()) { | if (!key.IsValid()) { | ||||
return false; | return false; | ||||
} | } | ||||
stakes.emplace_back( | return stakes | ||||
Stake(std::move(utxo), amount, height, is_coinbase, key.GetPubKey()), | .emplace(Stake(std::move(utxo), amount, height, is_coinbase, | ||||
std::move(key)); | key.GetPubKey()), | ||||
return true; | std::move(key)) | ||||
.second; | |||||
} | } | ||||
Proof ProofBuilder::build() { | Proof ProofBuilder::build() { | ||||
const ProofId proofid = getProofId(); | const ProofId proofid = getProofId(); | ||||
std::vector<SignedStake> signedStakes; | std::vector<SignedStake> signedStakes; | ||||
signedStakes.reserve(stakes.size()); | signedStakes.reserve(stakes.size()); | ||||
for (auto &s : stakes) { | while (!stakes.empty()) { | ||||
signedStakes.push_back(s.sign(proofid)); | auto handle = stakes.extract(stakes.begin()); | ||||
signedStakes.push_back(handle.value().sign(proofid)); | |||||
} | } | ||||
stakes.clear(); | |||||
return Proof(sequence, expirationTime, std::move(master), | return Proof(sequence, expirationTime, std::move(master), | ||||
std::move(signedStakes)); | std::move(signedStakes)); | ||||
} | } | ||||
ProofId ProofBuilder::getProofId() { | ProofId ProofBuilder::getProofId() const { | ||||
CHashWriter ss(SER_GETHASH, 0); | CHashWriter ss(SER_GETHASH, 0); | ||||
ss << sequence; | ss << sequence; | ||||
ss << expirationTime; | 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()); | WriteCompactSize(ss, stakes.size()); | ||||
for (const auto &s : stakes) { | for (const auto &s : stakes) { | ||||
ss << s.stake; | ss << s.stake; | ||||
} | } | ||||
CHashWriter ss2(SER_GETHASH, 0); | CHashWriter ss2(SER_GETHASH, 0); | ||||
ss2 << ss.GetHash(); | ss2 << ss.GetHash(); | ||||
ss2 << master; | ss2 << master; | ||||
return ProofId(ss2.GetHash()); | return ProofId(ss2.GetHash()); | ||||
} | } | ||||
} // namespace avalanche | } // namespace avalanche |