Skip to content
This repository has been archived by the owner on Jul 23, 2021. It is now read-only.

Commit

Permalink
Update: Overhauled Velocity Security System to v4
Browse files Browse the repository at this point in the history
  • Loading branch information
CryptoCoderz committed Jul 14, 2021
1 parent a85d05f commit b22d896
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 221 deletions.
2 changes: 1 addition & 1 deletion DigitalNote.pro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
TEMPLATE = app
TARGET = DigitalNote-qt
VERSION = 1.0.4.1
VERSION = 1.0.4.2
INCLUDEPATH += src src/json src/qt src/qt/plugins/mrichtexteditor
QT += core gui widgets network printsupport
DEFINES += ENABLE_WALLET
Expand Down
2 changes: 1 addition & 1 deletion src/clientversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#define CLIENT_VERSION_MAJOR 1
#define CLIENT_VERSION_MINOR 0
#define CLIENT_VERSION_REVISION 4
#define CLIENT_VERSION_BUILD 1
#define CLIENT_VERSION_BUILD 2

// Set to true for release, false for prerelease or test build
#define CLIENT_VERSION_IS_RELEASE true
Expand Down
135 changes: 34 additions & 101 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ bool AreInputsStandard(const CTransaction& tx, const MapPrevTx& mapInputs)

for (unsigned int i = 0; i < tx.vin.size(); i++)
{
const CTxOut& prev = tx.GetOutputFor(tx.vin[i], mapInputs, false);
const CTxOut& prev = tx.GetOutputFor(tx.vin[i], mapInputs);

vector<vector<unsigned char> > vSolutions;
txnouttype whichType;
Expand Down Expand Up @@ -662,7 +662,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const MapPrevTx& inputs)
unsigned int nSigOps = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
const CTxOut& prevout = tx.GetOutputFor(tx.vin[i], inputs, false);
const CTxOut& prevout = tx.GetOutputFor(tx.vin[i], inputs);
if (prevout.scriptPubKey.IsPayToScriptHash())
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
}
Expand Down Expand Up @@ -735,24 +735,6 @@ double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSiz
return dPriorityInputs / nTxSize;
}

void CTransaction::GetMapTxInputs(MapPrevTx& mapInputs, bool fAcceptBlock) const
{
// Load TX inputs
CTxDB txdb("r");
map<uint256, CTxIndex> mapUnused;
bool fInvalid = false;

// Ensure we can fetch inputs
if (!this->FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid, fAcceptBlock))
{
if (fInvalid)
{
LogPrintf("Invalid TX attempted to set in GetMapTXInputs\n");
return;
}
}
}

bool CTransaction::CheckTransaction() const
{
// Basic checks that don't depend on any context
Expand Down Expand Up @@ -912,7 +894,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool fLimitFree,
MapPrevTx mapInputs;
map<uint256, CTxIndex> mapUnused;
bool fInvalid = false;
if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid, false))
if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
{
if (fInvalid)
return error("AcceptToMemoryPool : FetchInputs found invalid tx %s", hash.ToString());
Expand All @@ -935,8 +917,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool fLimitFree,
error("AcceptToMemoryPool : too many sigops %s, %d > %d",
hash.ToString(), nSigOps, MAX_TX_SIGOPS));

int64_t nFees = tx.GetValueMapIn(mapInputs, false)-tx.GetValueOut();
if (tx.GetValueMapIn(mapInputs, false) < tx.GetValueOut()) {
int64_t nFees = tx.GetValueMapIn(mapInputs)-tx.GetValueOut();
if (tx.GetValueMapIn(mapInputs) < tx.GetValueOut()) {
LogPrintf("AcceptToMemoryPool : tx input is less that output\n");
return tx.DoS(100, error("AcceptToMemoryPool : tx input is less that output"));
}
Expand Down Expand Up @@ -1078,7 +1060,7 @@ bool AcceptableInputs(CTxMemPool& pool, const CTransaction &txo, bool fLimitFree
MapPrevTx mapInputs;
map<uint256, CTxIndex> mapUnused;
bool fInvalid = false;
if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid, false))
if (!tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
{
if (fInvalid)
return error("AcceptableInputs : FetchInputs found invalid tx %s", hash.ToString());
Expand All @@ -1101,8 +1083,8 @@ bool AcceptableInputs(CTxMemPool& pool, const CTransaction &txo, bool fLimitFree
error("AcceptableInputs : too many sigops %s, %d > %d",
hash.ToString(), nSigOps, MAX_TX_SIGOPS));

int64_t nFees = tx.GetValueMapIn(mapInputs, false)-tx.GetValueOut();
if (tx.GetValueMapIn(mapInputs, false) < tx.GetValueOut()) {
int64_t nFees = tx.GetValueMapIn(mapInputs)-tx.GetValueOut();
if (tx.GetValueMapIn(mapInputs) < tx.GetValueOut()) {
LogPrintf("AcceptableInputs : tx input is less that output\n");
return error("AcceptableInputs : tx input is less than output");
}
Expand Down Expand Up @@ -1594,7 +1576,7 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb)


bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTestPool,
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid, bool fAcceptBlock) const
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid) const
{
// FetchInputs can return false either because we just haven't seen some inputs
// (in which case the transaction should be stored as an orphan)
Expand Down Expand Up @@ -1632,54 +1614,39 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
{
// Get prev tx from single transactions in memory
if (!mempool.lookup(prevout.hash, txPrev)) {
if (!fAcceptBlock) {
return error("FetchInputs() : %s mempool Tx prev not found %s", GetHash().ToString(), prevout.hash.ToString());
} else {
LogPrintf("FetchInputs() : fAcceptBlock toggled, Skipping mempool Tx prev not found error \n");
}
}
if (!fFound) {
if (!mempool.lookup(prevout.hash, txPrev))
return error("FetchInputs() : %s mempool Tx prev not found %s", GetHash().ToString(), prevout.hash.ToString());
if (!fFound)
txindex.vSpent.resize(txPrev.vout.size());
}
}
else
{
// Get prev tx from disk
if (!txPrev.ReadFromDisk(txindex.pos)) {
if (!fAcceptBlock) {
return error("FetchInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString(), prevout.hash.ToString());
} else {
LogPrintf("FetchInputs() : fAcceptBlock toggled, Skipping ReadFromDisk Tx prev not found error \n");
}
}
if (!txPrev.ReadFromDisk(txindex.pos))
return error("FetchInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString(), prevout.hash.ToString());
}
}

if (!fAcceptBlock) {
// Make sure all prevout.n indexes are valid:
for (unsigned int i = 0; i < vin.size(); i++)
// Make sure all prevout.n indexes are valid:
for (unsigned int i = 0; i < vin.size(); i++)
{
const COutPoint prevout = vin[i].prevout;
assert(inputsRet.count(prevout.hash) != 0);
const CTxIndex& txindex = inputsRet[prevout.hash].first;
const CTransaction& txPrev = inputsRet[prevout.hash].second;
if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
{
const COutPoint prevout = vin[i].prevout;
assert(inputsRet.count(prevout.hash) != 0);
const CTxIndex& txindex = inputsRet[prevout.hash].first;
const CTransaction& txPrev = inputsRet[prevout.hash].second;
if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
{
// Revisit this if/when transaction replacement is implemented and allows
// adding inputs:
fInvalid = true;
return DoS(100, error("FetchInputs() : %s prevout.n out of range %d %u %u prev tx %s\n%s", GetHash().ToString(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString(), txPrev.ToString()));
}
// Revisit this if/when transaction replacement is implemented and allows
// adding inputs:
fInvalid = true;
return DoS(100, error("FetchInputs() : %s prevout.n out of range %d %u %u prev tx %s\n%s", GetHash().ToString(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString(), txPrev.ToString()));
}
} else {
LogPrintf("FetchInputs() : fAcceptBlock toggled, Skipping prevout.n validation \n");
}

return true;
}

const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& inputs, bool fAcceptBlock) const
const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const
{
MapPrevTx::const_iterator mi = inputs.find(input.prevout.hash);
if (mi == inputs.end()) {
Expand All @@ -1689,26 +1656,22 @@ const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& in
const CTransaction& txPrev = (mi->second).second;
// Don't allow oversized outputs
if (input.prevout.n >= txPrev.vout.size()) {
// Skip if queried by AcceptBlock()
if (!fAcceptBlock) {
throw std::runtime_error("CTransaction::GetOutputFor() : prevout.n out of range");
}
throw std::runtime_error("CTransaction::GetOutputFor() : prevout.n out of range");
}

return txPrev.vout[input.prevout.n];
}

int64_t CTransaction::GetValueMapIn(const MapPrevTx& inputs, bool fAcceptBlock) const
int64_t CTransaction::GetValueMapIn(const MapPrevTx& inputs) const
{
if (IsCoinBase())
return 0;

int64_t nResult = 0;
for (unsigned int i = 0; i < vin.size(); i++)
{
nResult += GetOutputFor(vin[i], inputs, fAcceptBlock).nValue;
nResult += GetOutputFor(vin[i], inputs).nValue;
}

return nResult;

}
Expand Down Expand Up @@ -1927,7 +1890,7 @@ void CBlock::RebuildAddressIndex(CTxDB& txdb)
MapPrevTx mapInputs;
map<uint256, CTxIndex> mapQueuedChangesT;
bool fInvalid;
if (!tx.FetchInputs(txdb, mapQueuedChangesT, true, false, mapInputs, fInvalid, false))
if (!tx.FetchInputs(txdb, mapQueuedChangesT, true, false, mapInputs, fInvalid))
return;

MapPrevTx::const_iterator mi;
Expand Down Expand Up @@ -2010,7 +1973,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
else
{
bool fInvalid;
if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid, false))
if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid))
return false;

// Add in sigops done by pay-to-script-hash inputs;
Expand All @@ -2020,7 +1983,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
if (nSigOps > MAX_BLOCK_SIGOPS)
return DoS(100, error("ConnectBlock() : too many sigops"));

int64_t nTxValueIn = tx.GetValueMapIn(mapInputs, false);
int64_t nTxValueIn = tx.GetValueMapIn(mapInputs);
int64_t nTxValueOut = tx.GetValueOut();
nValueIn += nTxValueIn;
nValueOut += nTxValueOut;
Expand Down Expand Up @@ -2092,7 +2055,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
MapPrevTx mapInputs;
map<uint256, CTxIndex> mapQueuedChangesT;
bool fInvalid;
if (!tx.FetchInputs(txdb, mapQueuedChangesT, true, false, mapInputs, fInvalid, false))
if (!tx.FetchInputs(txdb, mapQueuedChangesT, true, false, mapInputs, fInvalid))
return false;

MapPrevTx::const_iterator mi;
Expand Down Expand Up @@ -2965,42 +2928,12 @@ bool CBlock::AcceptBlock()
if (GetBlockTime() <= pindexPrev->GetPastTimeLimit() || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
return error("AcceptBlock() : block's timestamp is too early");

// Set logged values
CAmount tx_inputs_values = 0;
CAmount tx_outputs_values = 0;
CAmount tx_MapIn_values = 0;
CAmount tx_threshold = (300 * COIN);
// Check that all transactions are finalized
BOOST_FOREACH(const CTransaction& tx, vtx)
{
if (!IsFinalTx(tx, nHeight, GetBlockTime())) {
return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
}
// Log inputs/output values
MapPrevTx mapInputs;
tx.GetMapTxInputs(mapInputs, true);
tx_MapIn_values = tx.GetValueMapIn(mapInputs, true);
// Log inputs/output values
if((tx_inputs_values + tx_MapIn_values) >= 0)
{
tx_inputs_values += tx_MapIn_values;
} else {
return DoS(10, error("AcceptBlock() : overflow detected tx_inputs_values + tx.GetValueMapIn(mapInputs)"));
}
if(tx_outputs_values + tx.GetValueOut() >= 0)
{
tx_outputs_values += tx.GetValueOut();
} else {
return DoS(10, error("AcceptBlock() : overflow detected tx_outputs_values + tx.GetValueOut()"));
}
}

// Ensure input/output sanity of transactions in the block
if((tx_inputs_values + tx_threshold) < tx_outputs_values)
{
if(nHeight > 175) {
return DoS(100, error("AcceptBlock() : block contains a tx input that is less that output"));
}
}

// Check that the block chain matches the known block chain up to a checkpoint
Expand Down
12 changes: 6 additions & 6 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static const int64_t MIN_RELAY_TX_FEE = MIN_TX_FEE;
/** Minimum TX count (for relaying) */
static const int64_t MIN_TX_COUNT = 0;
/** Minimum TX value (for relaying) */
static const int64_t MIN_TX_VALUE = 0.01 * COIN;
static const int64_t MIN_TX_VALUE = 1 * COIN;
/** No amount larger than this (in satoshi) is valid */
static const int64_t MAX_SINGLE_TX = 10000000000 * COIN; // 10 Billion DigitalNote coins
/** Moneyrange params */
Expand All @@ -79,6 +79,8 @@ static const int64_t nDrift = 5 * 60;
inline int64_t FutureDrift(int64_t nTime) { return nTime + nDrift; }
/** "reject" message codes **/
static const unsigned char REJECT_INVALID = 0x10;
/** Velocity Factor handling toggle */
inline bool FACTOR_TOGGLE(int nHeight) { return TestNet() || nHeight > 394623; }

extern CScript COINBASE_FLAGS;
extern CCriticalSection cs_main;
Expand Down Expand Up @@ -328,8 +330,6 @@ class CTransaction
}
return nValueOut;
}
// Map TX inputs for scanning
void GetMapTxInputs(MapPrevTx &mapInputs, bool fAcceptBlock) const;

/** Amount of bitcoins coming in to this transaction
Note that lightweight clients may not know anything besides the hash of previous transactions,
Expand All @@ -339,7 +339,7 @@ class CTransaction
@return Sum of value of all inputs (scriptSigs)
@see CTransaction::FetchInputs
*/
int64_t GetValueMapIn(const MapPrevTx& mapInputs, bool fAcceptBlock) const;
int64_t GetValueMapIn(const MapPrevTx& mapInputs) const;

bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
{
Expand Down Expand Up @@ -418,7 +418,7 @@ class CTransaction
@return Returns true if all inputs are in txdb or mapTestPool
*/
bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid, bool fAcceptBlock) const;
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid) const;

/** Sanity check previous transactions, then, if all checks succeed,
mark them as spent by this transaction.
Expand All @@ -437,7 +437,7 @@ class CTransaction
bool CheckTransaction() const;
bool GetCoinAge(CTxDB& txdb, const CBlockIndex* pindexPrev, uint64_t& nCoinAge) const;

const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs, bool fAcceptBlock) const;
const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
};


Expand Down
4 changes: 2 additions & 2 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,10 @@ CBlock* CreateNewBlock(CReserveKey& reservekey, bool fProofOfStake, int64_t* pFe
map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
MapPrevTx mapInputs;
bool fInvalid;
if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid, false))
if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
continue;

int64_t nTxFees = tx.GetValueMapIn(mapInputs, false)-tx.GetValueOut();
int64_t nTxFees = tx.GetValueMapIn(mapInputs)-tx.GetValueOut();

nTxSigOps += GetP2SHSigOpCount(tx, mapInputs);
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
Expand Down
4 changes: 2 additions & 2 deletions src/rpcmining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,9 +621,9 @@ Value getblocktemplate(const Array& params, bool fHelp)
MapPrevTx mapInputs;
map<uint256, CTxIndex> mapUnused;
bool fInvalid = false;
if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid, false))
if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
{
entry.push_back(Pair("fee", (int64_t)(tx.GetValueMapIn(mapInputs, false) - tx.GetValueOut())));
entry.push_back(Pair("fee", (int64_t)(tx.GetValueMapIn(mapInputs) - tx.GetValueOut())));

Array deps;
BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs)
Expand Down
2 changes: 1 addition & 1 deletion src/rpcrawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ Value signrawtransaction(const Array& params, bool fHelp)

// FetchInputs aborts on failure, so we go one at a time.
tempTx.vin.push_back(mergedTx.vin[i]);
tempTx.FetchInputs(txdb, unused, false, false, mapPrevTx, fInvalid, false);
tempTx.FetchInputs(txdb, unused, false, false, mapPrevTx, fInvalid);

// Copy results into mapPrevOut:
BOOST_FOREACH(const CTxIn& txin, tempTx.vin)
Expand Down
2 changes: 1 addition & 1 deletion src/rpcvelocity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ json_spirit::Value getvelocityinfo(const Array& params, bool fHelp) {
obj.push_back(json_spirit::Pair("min-value", (int)VELOCITY_MIN_VALUE[i]));
if( VELOCITY_MIN_FEE[i] > 0 )
obj.push_back(json_spirit::Pair("min-fee", (int)VELOCITY_MIN_FEE[i]));
obj.push_back(json_spirit::Pair("factor", VELOCITY_FACTOR[i]));
obj.push_back(json_spirit::Pair("factor", VELOCITY_FACTOR));
obj.push_back(json_spirit::Pair("explicit", VELOCITY_EXPLICIT[i]));
return obj;
}

0 comments on commit b22d896

Please sign in to comment.