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 <avalanche/validation.h> | ||||
#include <coins.h> // For SaltedOutpointHasher | #include <coins.h> | ||||
#include <hash.h> | #include <hash.h> | ||||
#include <script/standard.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 { | ||||
CHashWriter ss(SER_GETHASH, 0); | CHashWriter ss(SER_GETHASH, 0); | ||||
ss << proofid; | ss << proofid; | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | for (const SignedStake &ss : stakes) { | ||||
if (!ss.verify(proofid)) { | if (!ss.verify(proofid)) { | ||||
return state.Invalid(ProofValidationResult::INVALID_SIGNATURE); | return state.Invalid(ProofValidationResult::INVALID_SIGNATURE); | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool Proof::verify(ProofValidationState &state, const CCoinsView &view) const { | |||||
if (!verify(state)) { | |||||
// state is set by verify. | |||||
return false; | |||||
} | |||||
for (const SignedStake &ss : stakes) { | |||||
const Stake &s = ss.getStake(); | |||||
const COutPoint &utxo = s.getUTXO(); | |||||
Coin coin; | |||||
if (!view.GetCoin(utxo, coin)) { | |||||
// The coins are not in the UTXO set. | |||||
return state.Invalid(ProofValidationResult::MISSING_UTXO); | |||||
} | |||||
const CTxOut &out = coin.GetTxOut(); | |||||
if (s.getAmount() != out.nValue) { | |||||
// Wrong amount. | |||||
return state.Invalid(ProofValidationResult::AMOUNT_MISMATCH); | |||||
} | |||||
CTxDestination dest; | |||||
if (!ExtractDestination(out.scriptPubKey, dest)) { | |||||
// Can't extract destination. | |||||
return state.Invalid( | |||||
ProofValidationResult::NON_STANDARD_DESTINATION); | |||||
} | |||||
PKHash *pkhash = boost::get<PKHash>(&dest); | |||||
if (!pkhash) { | |||||
// Only PKHash are supported. | |||||
return state.Invalid( | |||||
ProofValidationResult::DESTINATION_NOT_SUPPORTED); | |||||
} | |||||
const CPubKey &pubkey = s.getPubkey(); | |||||
if (*pkhash != PKHash(pubkey)) { | |||||
// Wrong pubkey. | |||||
return state.Invalid(ProofValidationResult::DESTINATION_MISMACTCH); | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
} // namespace avalanche | } // namespace avalanche |