From e2474103f0993b219525f6a757c712b5edf157f4 Mon Sep 17 00:00:00 2001 From: Nathan Marley Date: Mon, 17 Sep 2018 11:30:29 -0700 Subject: [PATCH] document spork system with doxygen comments This is an initial shot at an on-going WIP, which will add documentation via Doxygen comments to (especially) Dash-specific features in the codebase. --- src/spork.cpp | 3 - src/spork.h | 150 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 145 insertions(+), 8 deletions(-) diff --git a/src/spork.cpp b/src/spork.cpp index a9963eb138c2..ad67ec6933e6 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -237,7 +237,6 @@ bool CSporkManager::UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman) return false; } -// grab the spork, otherwise say it's off bool CSporkManager::IsSporkActive(int nSporkID) { LOCK(cs); @@ -255,7 +254,6 @@ bool CSporkManager::IsSporkActive(int nSporkID) return false; } -// grab the value of the spork on the network, or the default int64_t CSporkManager::GetSporkValue(int nSporkID) { LOCK(cs); @@ -382,7 +380,6 @@ std::string CSporkManager::ToString() const return strprintf("Sporks: %llu", mapSporksActive.size()); } - uint256 CSporkMessage::GetHash() const { return SerializeHash(*this); diff --git a/src/spork.h b/src/spork.h index 85e44a33ee10..0b61a7154d49 100644 --- a/src/spork.h +++ b/src/spork.h @@ -35,11 +35,24 @@ static const int SPORK_END = SPORK_ extern std::map mapSporkDefaults; extern CSporkManager sporkManager; -// -// Spork classes -// Keep track of all of the network spork settings -// +/** + * Sporks are network parameters used primarily to prevent forking and turn + * on/off certain features. They are a soft consensus mechanism. + * + * We use 2 main classes to manage the spork system. + * + * SporkMessages - low-level constructs which contain the sporkID, value, + * signature and a signature timestamp + * SporkManager - a higher-level construct which manages the naming, use of + * sporks, signatures and verification, and which sporks are active according + * to this node + */ +/** + * CSporkMessage is a low-level class used to encapsulate Spork messages and + * serialize them for transmission to other peers. This includes the internal + * spork ID, value, spork signature and timestamp for the signature. + */ class CSporkMessage { private: @@ -73,16 +86,49 @@ class CSporkMessage READWRITE(vchSig); } + /** + * GetHash returns the double-sha256 hash of the serialized spork message. + */ uint256 GetHash() const; + + /** + * GetSignatureHash returns the hash of the serialized spork message + * without the signature included. The intent of this method is to get the + * hash to be signed. + */ uint256 GetSignatureHash() const; + /** + * Sign will sign the spork message with the given key. + */ bool Sign(const CKey& key, bool fSporkSixActive); + + /** + * CheckSignature will ensure the spork signature matches the provided public + * key hash. + */ bool CheckSignature(const CKeyID& pubKeyId, bool fSporkSixActive) const; + + /** + * GetSignerKeyID is used to recover the spork address of the key used to + * sign this spork message. + * + * This method was introduced along with the multi-signer sporks feature, + * in order to identify which spork key signed this message. + */ bool GetSignerKeyID(CKeyID& retKeyidSporkSigner, bool fSporkSixActive); + + /** + * Relay is used to send this spork message to other peers. + */ void Relay(CConnman& connman); }; - +/** + * CSporkManager is a higher-level class which manages the node's spork + * messages, rules for which sporks should be considered active/inactive, and + * processing for certain sporks (e.g. spork 12). + */ class CSporkManager { private: @@ -96,7 +142,12 @@ class CSporkManager int nMinSporkKeys; CKey sporkPrivKey; + /** + * SporkValueIsActive is used to get the value agreed upon by the majority + * of signed spork messages for a given Spork ID. + */ bool SporkValueIsActive(int nSporkID, int64_t& nActiveValueRet) const; + public: CSporkManager() {} @@ -123,24 +174,113 @@ class CSporkManager // we don't serialize private key to prevent its leakage } + /** + * Clear is used to clear all in-memory active spork messages. Since spork + * public and private keys are set in init.cpp, we do not clear them here. + * + * This method was introduced along with the spork cache. + */ void Clear(); + + /** + * CheckAndRemove is defined to fulfill an interface as part of the on-disk + * cache used to cache sporks between runs. If sporks that are restored + * from cache do not have valid signatures when compared against the + * current spork private keys, they are removed from in-memory storage. + * + * This method was introduced along with the spork cache. + */ void CheckAndRemove(); + /** + * ProcessSpork is used to handle the 'getsporks' and 'spork' p2p messages. + * + * For 'getsporks', it sends active sporks to the requesting peer. For 'spork', + * it validates the spork and adds it to the internal spork storage and + * performs any necessary processing. + */ void ProcessSpork(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman); + + /** + * ExecuteSpork is used to perform certain actions based on the spork value. + * + * Currently only used with Spork 12. + */ void ExecuteSpork(int nSporkID, int nValue); + + /** + * UpdateSpork is used by the spork RPC command to set a new spork value, sign + * and broadcast the spork message. + */ bool UpdateSpork(int nSporkID, int64_t nValue, CConnman& connman); + /** + * IsSporkActive returns a bool for time-based sporks, and should be used + * to determine whether the spork can be considered active or not. + * + * For value-based sporks such as SPORK_5_INSTANTSEND_MAX_VALUE, the spork + * value should not be considered a timestamp, but an integer value + * instead, and therefore this method doesn't make sense and should not be + * used. + */ bool IsSporkActive(int nSporkID); + + /** + * GetSporkValue returns the spork value given a Spork ID. If no active spork + * message has yet been received by the node, it returns the default value. + */ int64_t GetSporkValue(int nSporkID); + + /** + * GetSporkIDByName returns the internal Spork ID given the spork name. + */ int GetSporkIDByName(const std::string& strName); + + /** + * GetSporkNameByID returns the spork name as a string, given a Spork ID. + */ std::string GetSporkNameByID(int nSporkID); + /** + * GetSporkByHash returns a spork message given a hash of the spork message. + * + * This is used when a requesting peer sends a MSG_SPORK inventory message with + * the hash, to quickly lookup and return the full spork message. We maintain a + * hash-based index of sporks for this reason, and this function is the access + * point into that index. + */ bool GetSporkByHash(const uint256& hash, CSporkMessage &sporkRet); + /** + * SetSporkAddress is used to set a public key ID which will be used to + * verify spork signatures. + * + * This can be called multiple times to add multiple keys to the set of + * valid spork signers. + */ bool SetSporkAddress(const std::string& strAddress); + + /** + * SetMinSporkKeys is used to set the required spork signer threshold, for + * a spork to be considered active. + * + * This value must be at least a majority of the total number of spork + * keys, and for obvious resons cannot be larger than that number. + */ bool SetMinSporkKeys(int minSporkKeys); + + /** + * SetPrivKey is used to set a spork key to enable setting / signing of + * spork values. + * + * This will return false if the private key does not match any spork + * address in the set of valid spork signers (see SetSporkAddress). + */ bool SetPrivKey(const std::string& strPrivKey); + /** + * ToString returns the string representation of the SporkManager. + */ std::string ToString() const; };