X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=e14b73ebc694ae4e3680341faae1d021c61b81c8;hb=a2d67b52d688d3044927a3b534d0450b6559f5cd;hp=6e7d2a40f9ea58de36e1cf125eb0b8b27a24c3e9;hpb=ecf1815faa0e16811c13f01b608336212b0b9070;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index 6e7d2a4..e14b73e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -309,12 +309,18 @@ bool CTransaction::IsStandard() const return false; if (!txin.scriptSig.IsPushOnly()) return false; + if (fEnforceCanonical && !txin.scriptSig.HasCanonicalPushes()) { + return false; + } } BOOST_FOREACH(const CTxOut& txout, vout) { if (!::IsStandard(txout.scriptPubKey)) return false; if (txout.nValue == 0) return false; + if (fEnforceCanonical && !txout.scriptPubKey.HasCanonicalPushes()) { + return false; + } } return true; } @@ -476,10 +482,8 @@ bool CTransaction::CheckTransaction() const if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake()) return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); - // NovaCoin: enforce minimum output amount for user transactions until 1 May 2014 04:00:00 GMT - if (!fTestNet && !IsCoinBase() && !txout.IsEmpty() && nTime < OUTPUT_SWITCH_TIME && txout.nValue < MIN_TXOUT_AMOUNT) - return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum")); - + if (txout.nValue < 0) + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue is negative")); if (txout.nValue > MAX_MONEY) return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high")); nValueOut += txout.nValue; @@ -511,18 +515,58 @@ bool CTransaction::CheckTransaction() const return true; } -int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, - enum GetMinFee_mode mode, unsigned int nBytes) const +int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, enum GetMinFee_mode mode, unsigned int nBytes) const { - // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE - int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; + // Use new fees approach if we are on test network or + // switch date has been reached + bool fNewApproach = fTestNet || nTime > FEE_SWITCH_TIME; + + int64 nMinTxFee = MIN_TX_FEE, nMinRelayTxFee = MIN_RELAY_TX_FEE; + + if(!fNewApproach || IsCoinStake()) + { + // Enforce 0.01 as minimum fee for old approach or coinstake + nMinTxFee = CENT; + nMinRelayTxFee = CENT; + } + + // Base fee is either nMinTxFee or nMinRelayTxFee + int64 nBaseFee = (mode == GMF_RELAY) ? nMinRelayTxFee : nMinTxFee; unsigned int nNewBlockSize = nBlockSize + nBytes; int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; - // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01 - if (nMinFee < nBaseFee) + if (fNewApproach) + { + if (fAllowFree) + { + if (nBlockSize == 1) + { + // Transactions under 1K are free + if (nBytes < 1000) + nMinFee = 0; + } + else + { + // Free transaction area + if (nNewBlockSize < 27000) + nMinFee = 0; + } + } + + // To limit dust spam, require additional MIN_TX_FEE/MIN_RELAY_TX_FEE for + // each non empty output which is less than 0.01 + // + // It's safe to ignore empty outputs here, because these inputs are allowed + // only for coinbase and coinstake transactions. + BOOST_FOREACH(const CTxOut& txout, vout) + if (txout.nValue < CENT && !txout.IsEmpty()) + nMinFee += nBaseFee; + } + else if (nMinFee < nBaseFee) { + // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if + // any output is less than 0.01 BOOST_FOREACH(const CTxOut& txout, vout) if (txout.nValue < CENT) nMinFee = nBaseFee; @@ -538,6 +582,7 @@ int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, if (!MoneyRange(nMinFee)) nMinFee = MAX_MONEY; + return nMinFee; } @@ -632,7 +677,7 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Don't accept it if it can't get into a block - int64 txMinFee = tx.GetMinFee(1000, false, GMF_RELAY, nSize); + int64 txMinFee = tx.GetMinFee(1000, true, GMF_RELAY, nSize); if (nFees < txMinFee) return error("CTxMemPool::accept() : not enough fees %s, %"PRI64d" < %"PRI64d, hash.ToString().c_str(), @@ -1486,11 +1531,13 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, mapnBits, nTime) - GetMinFee() + MIN_TX_FEE; + unsigned int nTxSize = (nTime > VALIDATION_SWITCH_TIME || fTestNet) ? GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) : 0; - if (nStakeReward > nCalculatedStakeReward) - return DoS(100, error("ConnectInputs() : coinstake pays too much(actual=%"PRI64d" vs calculated=%"PRI64d")", nStakeReward, nCalculatedStakeReward)); + int64 nReward = GetValueOut() - nValueIn; + int64 nCalculatedReward = GetProofOfStakeReward(nCoinAge, pindexBlock->nBits, nTime) - GetMinFee(1, false, GMF_BLOCK, nTxSize) + CENT; + + if (nReward > nCalculatedReward) + return DoS(100, error("CheckInputs() : coinstake pays too much(actual=%"PRI64d" vs calculated=%"PRI64d")", nReward, nCalculatedReward)); } else { @@ -1502,10 +1549,6 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, mapnVersion < 60010) + { + printf("partner %s using a buggy client %d, disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + pfrom->fDisconnect = true; + return true; + } + // record my external IP reported by peer if (addrFrom.IsRoutable() && addrMe.IsRoutable()) addrSeenByPeer = addrMe;