Skip to content

Commit 16f6906

Browse files
authored
Merge pull request #63 from CryptoCoderz/master
Added: In depth block scan during validation for added security
2 parents b3245ea + 56df7b7 commit 16f6906

6 files changed

Lines changed: 64 additions & 14 deletions

File tree

src/chainparams.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class CMainParams : public CChainParams {
113113
nPoolMaxTransactions = 9;
114114
strMNenginePoolDummyAddress = "dUnVN6zz2apaoWkb5krGoBCwwo8ZD3axue";
115115
strDevOpsAddress = "dSCXLHTZJJqTej8ZRszZxbLrS6dDGVJhw7";
116-
nEndPoWBlock = 394624;
116+
nEndPoWBlock = 999999;
117117
nStartPoSBlock = 0;
118118
}
119119

src/main.cpp

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,23 @@ double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSiz
735735
return dPriorityInputs / nTxSize;
736736
}
737737

738+
void CTransaction::GetMapTxInputs(MapPrevTx& mapInputs) const
739+
{
740+
// Load TX inputs
741+
CTxDB txdb("r");
742+
map<uint256, CTxIndex> mapUnused;
743+
bool fInvalid = false;
744+
// Ensure we can fetch inputs
745+
if (!this->FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
746+
{
747+
if (fInvalid)
748+
{
749+
LogPrintf("Invalid TX attempted to set in GetMapTXInputs\n");
750+
return;
751+
}
752+
}
753+
}
754+
738755
bool CTransaction::CheckTransaction() const
739756
{
740757
// Basic checks that don't depend on any context
@@ -917,7 +934,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool fLimitFree,
917934
error("AcceptToMemoryPool : too many sigops %s, %d > %d",
918935
hash.ToString(), nSigOps, MAX_TX_SIGOPS));
919936

920-
int64_t nFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
937+
int64_t nFees = tx.GetValueMapIn(mapInputs)-tx.GetValueOut();
938+
if (tx.GetValueMapIn(mapInputs) < tx.GetValueOut()) {
939+
LogPrintf("AcceptToMemoryPool : tx input is less that output\n");
940+
return tx.DoS(100, error("AcceptToMemoryPool : tx input is less that output"));
941+
}
921942
unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
922943

923944
// Don't accept it if it can't get into a block
@@ -1079,7 +1100,11 @@ bool AcceptableInputs(CTxMemPool& pool, const CTransaction &txo, bool fLimitFree
10791100
error("AcceptableInputs : too many sigops %s, %d > %d",
10801101
hash.ToString(), nSigOps, MAX_TX_SIGOPS));
10811102

1082-
int64_t nFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
1103+
int64_t nFees = tx.GetValueMapIn(mapInputs)-tx.GetValueOut();
1104+
if (tx.GetValueMapIn(mapInputs) < tx.GetValueOut()) {
1105+
LogPrintf("AcceptableInputs : tx input is less that output\n");
1106+
return error("AcceptableInputs : tx input is less than output");
1107+
}
10831108
unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
10841109
int64_t txMinFee = GetMinFee(tx, nSize, true, GMF_RELAY);
10851110

@@ -1568,7 +1593,7 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb)
15681593

15691594

15701595
bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTestPool,
1571-
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid)
1596+
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid) const
15721597
{
15731598
// FetchInputs can return false either because we just haven't seen some inputs
15741599
// (in which case the transaction should be stored as an orphan)
@@ -1651,7 +1676,7 @@ const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& in
16511676
return txPrev.vout[input.prevout.n];
16521677
}
16531678

1654-
int64_t CTransaction::GetValueIn(const MapPrevTx& inputs) const
1679+
int64_t CTransaction::GetValueMapIn(const MapPrevTx& inputs) const
16551680
{
16561681
if (IsCoinBase())
16571682
return 0;
@@ -1972,12 +1997,17 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
19721997
if (nSigOps > MAX_BLOCK_SIGOPS)
19731998
return DoS(100, error("ConnectBlock() : too many sigops"));
19741999

1975-
int64_t nTxValueIn = tx.GetValueIn(mapInputs);
2000+
int64_t nTxValueIn = tx.GetValueMapIn(mapInputs);
19762001
int64_t nTxValueOut = tx.GetValueOut();
19772002
nValueIn += nTxValueIn;
19782003
nValueOut += nTxValueOut;
1979-
if (!tx.IsCoinStake())
2004+
if (!tx.IsCoinStake()) {
19802005
nFees += nTxValueIn - nTxValueOut;
2006+
if (nTxValueIn < nTxValueOut) {
2007+
LogPrintf("ConnectBlock : block contains a tx input that is less that output\n");
2008+
return false;
2009+
}
2010+
}
19812011
if (tx.IsCoinStake())
19822012
nStakeReward = nTxValueOut - nTxValueIn;
19832013

@@ -2912,10 +2942,28 @@ bool CBlock::AcceptBlock()
29122942
if (GetBlockTime() <= pindexPrev->GetPastTimeLimit() || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
29132943
return error("AcceptBlock() : block's timestamp is too early");
29142944

2945+
// Set logged values
2946+
CAmount tx_inputs_values = 0;
2947+
CAmount tx_outputs_values = 0;
2948+
CAmount tx_threshold = (300 * COIN);
29152949
// Check that all transactions are finalized
29162950
BOOST_FOREACH(const CTransaction& tx, vtx)
2917-
if (!IsFinalTx(tx, nHeight, GetBlockTime()))
2951+
{
2952+
if (!IsFinalTx(tx, nHeight, GetBlockTime())) {
29182953
return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
2954+
}
2955+
// Log inputs/output values
2956+
MapPrevTx mapInputs;
2957+
tx.GetMapTxInputs(mapInputs);
2958+
tx_inputs_values += tx.GetValueMapIn(mapInputs);
2959+
tx_outputs_values += tx.GetValueOut();
2960+
}
2961+
2962+
// Ensure input/output sanity of transactions in the block
2963+
if((tx_inputs_values + tx_threshold) < tx_outputs_values)
2964+
{
2965+
return DoS(100, error("AcceptBlock() : block contains a tx input that is less that output"));
2966+
}
29192967

29202968
// Check that the block chain matches the known block chain up to a checkpoint
29212969
if (!Checkpoints::CheckHardened(nHeight, hash))

src/main.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ class CTransaction
328328
}
329329
return nValueOut;
330330
}
331+
// Map TX inputs for scanning
332+
void GetMapTxInputs(MapPrevTx &mapInputs) const;
331333

332334
/** Amount of bitcoins coming in to this transaction
333335
Note that lightweight clients may not know anything besides the hash of previous transactions,
@@ -337,7 +339,7 @@ class CTransaction
337339
@return Sum of value of all inputs (scriptSigs)
338340
@see CTransaction::FetchInputs
339341
*/
340-
int64_t GetValueIn(const MapPrevTx& mapInputs) const;
342+
int64_t GetValueMapIn(const MapPrevTx& mapInputs) const;
341343

342344
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
343345
{
@@ -416,7 +418,7 @@ class CTransaction
416418
@return Returns true if all inputs are in txdb or mapTestPool
417419
*/
418420
bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
419-
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid);
421+
bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid) const;
420422

421423
/** Sanity check previous transactions, then, if all checks succeed,
422424
mark them as spent by this transaction.

src/miner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey, bool fProofOfStake, int64_t* pFe
316316
if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
317317
continue;
318318

319-
int64_t nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
319+
int64_t nTxFees = tx.GetValueMapIn(mapInputs)-tx.GetValueOut();
320320

321321
nTxSigOps += GetP2SHSigOpCount(tx, mapInputs);
322322
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)

src/rpcmining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
623623
bool fInvalid = false;
624624
if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid))
625625
{
626-
entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut())));
626+
entry.push_back(Pair("fee", (int64_t)(tx.GetValueMapIn(mapInputs) - tx.GetValueOut())));
627627

628628
Array deps;
629629
BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs)

src/velocity.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ bool Velocity(CBlockIndex* prevBlock, CBlock* block)
8585
BOOST_FOREACH(const CTransaction& tx, block->vtx)
8686
{
8787
TXvalue = tx.GetValueOut();
88-
TXinput = tx.GetValueIn(mapInputs);
88+
TXinput = tx.GetValueMapIn(mapInputs);
8989
TXfee = TXinput - TXvalue;
9090
TXcount = block->vtx.size();
9191
// TXlogic = GetPrevAccountBalance - TXinput;
@@ -169,7 +169,7 @@ bool Velocity(CBlockIndex* prevBlock, CBlock* block)
169169
{
170170
TXcount = block->vtx.size();
171171
TXvalue = tx.GetValueOut();
172-
TXinput = tx.GetValueIn(mapInputs);
172+
TXinput = tx.GetValueMapIn(mapInputs);
173173
TXfee = TXinput - TXvalue;
174174
if(TXfee > devopsPayment){
175175
TXnetfee = TXfee - devopsPayment;

0 commit comments

Comments
 (0)