Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/proof.cpp
// Copyright (c) 2020 The Bitcoin developers | // Copyright (c) 2020 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <avalanche/proof.h> | #include <avalanche/proof.h> | ||||
#include <avalanche/validation.h> | |||||
#include <coins.h> // For SaltedOutpointHasher | #include <coins.h> // For SaltedOutpointHasher | ||||
#include <hash.h> | #include <hash.h> | ||||
#include <unordered_set> | #include <unordered_set> | ||||
namespace avalanche { | namespace avalanche { | ||||
uint256 Stake::getHash(const ProofId &proofid) const { | uint256 Stake::getHash(const ProofId &proofid) const { | ||||
Show All 27 Lines | uint32_t Proof::getScore() const { | ||||
Amount total = Amount::zero(); | Amount total = Amount::zero(); | ||||
for (const SignedStake &s : stakes) { | for (const SignedStake &s : stakes) { | ||||
total += s.getStake().getAmount(); | total += s.getStake().getAmount(); | ||||
} | } | ||||
return uint32_t((100 * total) / COIN); | return uint32_t((100 * total) / COIN); | ||||
} | } | ||||
bool Proof::verify() const { | static constexpr Amount PROOF_DUST_THRESOLD = 1 * SATOSHI; | ||||
if (getScore() == 0) { | |||||
// No stake. | bool Proof::verify(ProofValidationState &state) const { | ||||
return false; | if (stakes.empty()) { | ||||
return state.Invalid(ProofValidationResult::NO_STAKE); | |||||
} | } | ||||
std::unordered_set<COutPoint, SaltedOutpointHasher> utxos; | std::unordered_set<COutPoint, SaltedOutpointHasher> utxos; | ||||
for (auto &s : stakes) { | for (const SignedStake &ss : stakes) { | ||||
if (!utxos.insert(s.getStake().getUTXO()).second) { | const Stake &s = ss.getStake(); | ||||
// Duplicated stake. | if (s.getAmount() < PROOF_DUST_THRESOLD) { | ||||
return false; | return state.Invalid(ProofValidationResult::DUST_THRESOLD); | ||||
} | |||||
if (!utxos.insert(s.getUTXO()).second) { | |||||
return state.Invalid(ProofValidationResult::DUPLICATE_STAKE); | |||||
} | } | ||||
if (!s.verify(proofid)) { | if (!ss.verify(proofid)) { | ||||
// Improperly signed stake. | return state.Invalid(ProofValidationResult::INVALID_SIGNATURE); | ||||
return false; | |||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
} // namespace avalanche | } // namespace avalanche |