Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/processor.cpp
Show First 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | static bool IsWorthPolling(const CBlockIndex *pindex) { | ||||
if (::ChainstateActive().IsBlockFinalized(pindex)) { | if (::ChainstateActive().IsBlockFinalized(pindex)) { | ||||
// There is no point polling finalized block. | // There is no point polling finalized block. | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static bool VerifyProof(const Proof &proof, bilingual_str &error) { | |||||
ProofValidationState proof_state; | |||||
if (!proof.verify(proof_state)) { | |||||
switch (proof_state.GetResult()) { | |||||
case ProofValidationResult::NO_STAKE: | |||||
error = _("The avalanche proof has no stake."); | |||||
return false; | |||||
case ProofValidationResult::DUST_THRESOLD: | |||||
error = _("The avalanche proof stake is too low."); | |||||
return false; | |||||
case ProofValidationResult::DUPLICATE_STAKE: | |||||
error = _("The avalanche proof has duplicated stake."); | |||||
return false; | |||||
case ProofValidationResult::INVALID_SIGNATURE: | |||||
error = _("The avalanche proof has invalid stake signatures."); | |||||
return false; | |||||
case ProofValidationResult::TOO_MANY_UTXOS: | |||||
error = strprintf( | |||||
_("The avalanche proof has too many utxos (max: %u)."), | |||||
AVALANCHE_MAX_PROOF_STAKES); | |||||
return false; | |||||
default: | |||||
error = _("The avalanche proof is invalid."); | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
static bool VerifyDelegation(const Delegation &dg, | |||||
const CPubKey &expectedPubKey, | |||||
bilingual_str &error) { | |||||
DelegationState dg_state; | |||||
CPubKey auth; | |||||
if (!dg.verify(dg_state, auth)) { | |||||
switch (dg_state.GetResult()) { | |||||
case avalanche::DelegationResult::INVALID_SIGNATURE: | |||||
error = _("The avalanche delegation has invalid signatures."); | |||||
return false; | |||||
default: | |||||
error = _("The avalanche delegation is invalid."); | |||||
return false; | |||||
} | |||||
} | |||||
if (auth != expectedPubKey) { | |||||
error = _( | |||||
"The avalanche delegation does not match the expected public key."); | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
struct Processor::PeerData { | struct Processor::PeerData { | ||||
std::shared_ptr<Proof> proof; | std::shared_ptr<Proof> proof; | ||||
Delegation delegation; | Delegation delegation; | ||||
}; | }; | ||||
class Processor::NotificationsHandler | class Processor::NotificationsHandler | ||||
: public interfaces::Chain::Notifications { | : public interfaces::Chain::Notifications { | ||||
Processor *m_processor; | Processor *m_processor; | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | if (argsman.IsArgSet("-avaproof")) { | ||||
peerData = std::make_unique<PeerData>(); | peerData = std::make_unique<PeerData>(); | ||||
peerData->proof = std::make_shared<Proof>(); | peerData->proof = std::make_shared<Proof>(); | ||||
if (!Proof::FromHex(*peerData->proof, argsman.GetArg("-avaproof", ""), | if (!Proof::FromHex(*peerData->proof, argsman.GetArg("-avaproof", ""), | ||||
error)) { | error)) { | ||||
// error is set by FromHex | // error is set by FromHex | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
ProofValidationState proof_state; | if (!VerifyProof(*peerData->proof, error)) { | ||||
if (!peerData->proof->verify(proof_state)) { | // error is set by VerifyProof | ||||
switch (proof_state.GetResult()) { | |||||
case ProofValidationResult::NO_STAKE: | |||||
error = _("The avalanche proof has no stake."); | |||||
return nullptr; | |||||
case ProofValidationResult::DUST_THRESOLD: | |||||
error = _("The avalanche proof stake is too low."); | |||||
return nullptr; | |||||
case ProofValidationResult::DUPLICATE_STAKE: | |||||
error = _("The avalanche proof has duplicated stake."); | |||||
return nullptr; | |||||
case ProofValidationResult::INVALID_SIGNATURE: | |||||
error = | |||||
_("The avalanche proof has invalid stake signatures."); | |||||
return nullptr; | |||||
case ProofValidationResult::TOO_MANY_UTXOS: | |||||
error = strprintf( | |||||
_("The avalanche proof has too many utxos (max: %u)."), | |||||
AVALANCHE_MAX_PROOF_STAKES); | |||||
return nullptr; | |||||
default: | |||||
error = _("The avalanche proof is invalid."); | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
} | |||||
const CPubKey masterPubKey = peerData->proof->getMaster(); | const CPubKey masterPubKey = peerData->proof->getMaster(); | ||||
if (masterKey.GetPubKey() != masterPubKey) { | if (masterKey.GetPubKey() != masterPubKey) { | ||||
error = _("The master key does not match the proof public key."); | error = _("The master key does not match the proof public key."); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
// Generate the delegation to the session key. | // Generate the delegation to the session key. | ||||
DelegationBuilder dgb(*peerData->proof); | DelegationBuilder dgb(*peerData->proof); | ||||
if (sessionKey.GetPubKey() != masterPubKey) { | const CPubKey sessionPubKey = sessionKey.GetPubKey(); | ||||
dgb.addLevel(masterKey, sessionKey.GetPubKey()); | if (sessionPubKey != masterPubKey) { | ||||
dgb.addLevel(masterKey, sessionPubKey); | |||||
} | } | ||||
peerData->delegation = dgb.build(); | peerData->delegation = dgb.build(); | ||||
if (!VerifyDelegation(peerData->delegation, sessionPubKey, error)) { | |||||
// error is set by VerifyDelegation | |||||
return nullptr; | |||||
} | |||||
} | } | ||||
// We can't use std::make_unique with a private constructor | // We can't use std::make_unique with a private constructor | ||||
return std::unique_ptr<Processor>( | return std::unique_ptr<Processor>( | ||||
new Processor(chain, connman, nodePeerManager, std::move(peerData), | new Processor(chain, connman, nodePeerManager, std::move(peerData), | ||||
std::move(sessionKey))); | std::move(sessionKey))); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 442 Lines • Show Last 20 Lines |