dash/src/spork.h

285 lines
9.4 KiB
C
Raw Normal View History

2016-12-20 14:26:45 +01:00
// Copyright (c) 2014-2017 The Dash Core developers
2015-02-09 21:54:51 +01:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2015-02-09 21:54:51 +01:00
#ifndef SPORK_H
#define SPORK_H
#include "hash.h"
#include "net.h"
#include "utilstrencodings.h"
#include "key.h"
2015-04-03 00:51:08 +02:00
class CSporkMessage;
class CSporkManager;
/*
Don't ever reuse these IDs for other sporks
- This would result in old clients getting confused about which spork is for what
*/
static const int SPORK_2_INSTANTSEND_ENABLED = 10001;
static const int SPORK_3_INSTANTSEND_BLOCK_FILTERING = 10002;
static const int SPORK_5_INSTANTSEND_MAX_VALUE = 10004;
static const int SPORK_6_NEW_SIGS = 10005;
static const int SPORK_9_SUPERBLOCKS_ENABLED = 10008;
static const int SPORK_12_RECONSIDER_BLOCKS = 10011;
Automatic InstantSend locks for "simple" transactions (#2140) * add locktransaction rpc call * Remove special instantsend fee for simple transactions * Function to check if trx is simple enough to be autolocked * Automatic lock for all received from peers simple trxes If we get a new transaction with CInv message and it is "simple" and is accepted in mempool, we initiate its lock. We don't lock orphan trxes that accepted in mempool after this trx because they are locked by other peers. * Automatically lock simple trxes in wallet * protocol bump for InstantSend without special fee * Add function to detect used mempool share * Mempool threshold for auto IX locks * Add SPORK_16_INSTANTSEND_AUTOLOCKS spork * Make autolocks active only when spork SPORK_16_INSTANTSEND_AUTOLOCKS is active * BIP9 autolocks activation * revert increasing min peer protocol version for mn rank * move IsTrxSimple check to CTxLockRequest class * make MAX_INPUTS_FOR_AUTO_IX private member of CTxLockRequest class * make AUTO_IX_MEMPOOL_THRESHOLD private member of CInstantSend class * remove locktransaction RPC call * tests for automatic IS locks * fix mempool threshod calculation * bump mocktime in activate_autoix_bip9 * set node times * no need to spam the node with gettransaction rpc requests that often * use `spork active` instead of leaking spork logic into tests * codestyle fixes * add test description in comments * fix typo * sync test nodes more often during BIP9 activation * Use 4th bit in BIP9 activation * Fix comments according codestyle guide * Call AcceptLockRequest and Vote at the first node creating autoix lock * fix mempool used memory calculation * rallback not necessary change in CWallet::CreateTransaction * test for stopping autolocks for full mempool * Inject "simple autolockable" txes into txlockrequest logic
2018-09-26 16:17:47 +02:00
static const int SPORK_16_INSTANTSEND_AUTOLOCKS = 10015;
static const int SPORK_17_QUORUM_DKG_ENABLED = 10016;
static const int SPORK_START = SPORK_2_INSTANTSEND_ENABLED;
static const int SPORK_END = SPORK_17_QUORUM_DKG_ENABLED;
extern std::map<int, int64_t> mapSporkDefaults;
2015-02-09 21:54:51 +01:00
extern CSporkManager sporkManager;
/**
* 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
*/
2015-02-09 21:54:51 +01:00
/**
* 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.
*/
2015-02-09 21:54:51 +01:00
class CSporkMessage
{
private:
2015-02-09 21:54:51 +01:00
std::vector<unsigned char> vchSig;
public:
2015-02-09 21:54:51 +01:00
int nSporkID;
2015-02-11 15:47:21 +01:00
int64_t nValue;
2015-02-09 21:54:51 +01:00
int64_t nTimeSigned;
CSporkMessage(int nSporkID, int64_t nValue, int64_t nTimeSigned) :
nSporkID(nSporkID),
nValue(nValue),
nTimeSigned(nTimeSigned)
{}
CSporkMessage() :
nSporkID(0),
nValue(0),
nTimeSigned(0)
{}
2015-02-09 21:54:51 +01:00
2015-04-03 00:51:08 +02:00
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
2015-02-09 21:54:51 +01:00
READWRITE(nSporkID);
2015-02-11 15:47:21 +01:00
READWRITE(nValue);
2015-02-09 21:54:51 +01:00
READWRITE(nTimeSigned);
READWRITE(vchSig);
2015-04-03 00:51:08 +02:00
}
/**
* 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);
2015-02-09 21:54:51 +01:00
};
/**
* 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).
*/
2015-02-09 21:54:51 +01:00
class CSporkManager
{
private:
2018-09-26 16:15:02 +02:00
static const std::string SERIALIZATION_VERSION_STRING;
mutable CCriticalSection cs;
std::map<uint256, CSporkMessage> mapSporksByHash;
std::map<int, std::map<CKeyID, CSporkMessage> > mapSporksActive;
2015-02-09 21:54:51 +01:00
std::set<CKeyID> setSporkPubKeyIDs;
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;
2015-02-09 21:54:51 +01:00
public:
CSporkManager() {}
2015-02-09 21:54:51 +01:00
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
2018-09-26 16:15:02 +02:00
std::string strVersion;
if(ser_action.ForRead()) {
READWRITE(strVersion);
if (strVersion != SERIALIZATION_VERSION_STRING) {
return;
}
} else {
strVersion = SERIALIZATION_VERSION_STRING;
READWRITE(strVersion);
}
// we don't serialize pubkey ids because pubkeys should be
// hardcoded or be setted with cmdline or options, should
// not reuse pubkeys from previous dashd run
READWRITE(mapSporksByHash);
READWRITE(mapSporksActive);
// 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.
*/
2018-09-26 16:15:02 +02:00
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);
2015-02-09 21:54:51 +01:00
/**
* 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;
2015-02-09 21:54:51 +01:00
};
2015-04-03 00:51:08 +02:00
#endif