Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/proof.cpp
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 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); | ||||
} | } | ||||
static constexpr Amount PROOF_DUST_THRESOLD = 1 * SATOSHI; | |||||
bool Proof::verify(ProofValidationState &state) const { | bool Proof::verify(ProofValidationState &state) const { | ||||
if (stakes.empty()) { | if (stakes.empty()) { | ||||
return state.Invalid(ProofValidationResult::NO_STAKE); | return state.Invalid(ProofValidationResult::NO_STAKE); | ||||
} | } | ||||
Amount totalAmount = Amount::zero(); | |||||
std::unordered_set<COutPoint, SaltedOutpointHasher> utxos; | std::unordered_set<COutPoint, SaltedOutpointHasher> utxos; | ||||
for (const SignedStake &ss : stakes) { | for (const SignedStake &ss : stakes) { | ||||
const Stake &s = ss.getStake(); | const Stake &s = ss.getStake(); | ||||
if (s.getAmount() < PROOF_DUST_THRESOLD) { | if (s.getAmount() < PROOF_DUST_THRESOLD) { | ||||
return state.Invalid(ProofValidationResult::DUST_THRESOLD); | return state.Invalid(ProofValidationResult::DUST_THRESOLD); | ||||
} | } | ||||
// Verify the total amount makes sense: in MoneyRange, no overflow | |||||
if (!MoneyRange(s.getAmount()) || | |||||
!MoneyRange(totalAmount + s.getAmount())) { | |||||
return state.Invalid(ProofValidationResult::INVALID_TOTAL_AMOUNT); | |||||
} | |||||
totalAmount += s.getAmount(); | |||||
if (!utxos.insert(s.getUTXO()).second) { | if (!utxos.insert(s.getUTXO()).second) { | ||||
return state.Invalid(ProofValidationResult::DUPLICATE_STAKE); | return state.Invalid(ProofValidationResult::DUPLICATE_STAKE); | ||||
} | } | ||||
if (!ss.verify(proofid)) { | if (!ss.verify(proofid)) { | ||||
return state.Invalid(ProofValidationResult::INVALID_SIGNATURE); | return state.Invalid(ProofValidationResult::INVALID_SIGNATURE); | ||||
} | } | ||||
} | } | ||||
if (totalAmount < PROOF_MIN_TOTAL_AMOUNT) { | |||||
return state.Invalid(ProofValidationResult::INSUFFICIENT_TOTAL_AMOUNT); | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
bool Proof::verify(ProofValidationState &state, const CCoinsView &view) const { | bool Proof::verify(ProofValidationState &state, const CCoinsView &view) const { | ||||
if (!verify(state)) { | if (!verify(state)) { | ||||
// state is set by verify. | // state is set by verify. | ||||
return false; | return false; | ||||
▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines |