#include "utilmoneystr.h"
#include "validationinterface.h"
#include "wallet/asyncrpcoperation_sendmany.h"
+#include "wallet/asyncrpcoperation_shieldcoinbase.h"
#include <sstream>
if (pfMissingInputs)
*pfMissingInputs = false;
+ // Node operator can choose to reject tx by number of transparent inputs
+ static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
+ size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
+ if (limit > 0) {
+ size_t n = tx.vin.size();
+ if (n > limit) {
+ LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
+ return false;
+ }
+ }
+
auto verifier = libzcash::ProofVerifier::Strict();
if (!CheckTransaction(tx, state, verifier))
return error("AcceptToMemoryPool: CheckTransaction failed");
bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
{
- if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams))
- return false;
-
if (!tx.IsCoinBase())
{
+ if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
+ return false;
+ }
+
if (pvChecks)
pvChecks->reserve(tx.vin.size());
REJECT_INVALID, "bad-txns-BIP30");
}
- unsigned int flags = SCRIPT_VERIFY_P2SH;
+ unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
- // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks,
- // when 75% of the network has upgraded:
- if (block.nVersion >= 3) {
- flags |= SCRIPT_VERIFY_DERSIG;
- }
-
- // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4
- // blocks, when 75% of the network has upgraded:
- if (block.nVersion >= 4) {
- flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
- }
+ // DERSIG (BIP66) is also always enforced, but does not have a flag.
CBlockUndo blockundo;
}
}
- // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
- // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
- // Since MIN_BLOCK_VERSION = 4 all blocks with nHeight > 0 should satisfy this.
- // This rule is not applied to the genesis block, which didn't include the height
- // in the coinbase.
+ // Enforce BIP 34 rule that the coinbase starts with serialized block height.
+ // In Zcash this has been enforced since launch, except that the genesis
+ // block didn't include the height in the coinbase (see Zcash protocol spec
+ // section '6.8 Bitcoin Improvement Proposals').
if (nHeight > 0)
{
CScript expect = CScript() << nHeight;
return false;
}
+ if (pfrom->nVersion == 10300)
+ pfrom->nVersion = 300;
if (!vRecv.empty())
vRecv >> addrFrom >> nNonce;
if (!vRecv.empty()) {
}
// Get recent addresses
- pfrom->PushMessage("getaddr");
- pfrom->fGetAddr = true;
+ if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
+ {
+ pfrom->PushMessage("getaddr");
+ pfrom->fGetAddr = true;
+ }
addrman.Good(pfrom->addr);
} else {
if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
vector<CAddress> vAddr;
vRecv >> vAddr;
+ // Don't want addr from older versions unless seeding
+ if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
+ return true;
if (vAddr.size() > 1000)
{
Misbehaving(pfrom->GetId(), 20);
multimap<uint256, CNode*> mapMix;
BOOST_FOREACH(CNode* pnode, vNodes)
{
+ if (pnode->nVersion < CADDR_TIME_VERSION)
+ continue;
unsigned int nPointer;
memcpy(&nPointer, &pnode, sizeof(nPointer));
uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
else if (strCommand == "ping")
{
- uint64_t nonce = 0;
- vRecv >> nonce;
- // Echo the message back with the nonce. This allows for two useful features:
- //
- // 1) A remote node can quickly check if the connection is operational
- // 2) Remote nodes can measure the latency of the network thread. If this node
- // is overloaded it won't respond to pings quickly and the remote node can
- // avoid sending us more work, like chain download requests.
- //
- // The nonce stops the remote getting confused between different pings: without
- // it, if the remote node sends a ping once per second and this node takes 5
- // seconds to respond to each, the 5th ping the remote sends would appear to
- // return very quickly.
- pfrom->PushMessage("pong", nonce);
+ if (pfrom->nVersion > BIP0031_VERSION)
+ {
+ uint64_t nonce = 0;
+ vRecv >> nonce;
+ // Echo the message back with the nonce. This allows for two useful features:
+ //
+ // 1) A remote node can quickly check if the connection is operational
+ // 2) Remote nodes can measure the latency of the network thread. If this node
+ // is overloaded it won't respond to pings quickly and the remote node can
+ // avoid sending us more work, like chain download requests.
+ //
+ // The nonce stops the remote getting confused between different pings: without
+ // it, if the remote node sends a ping once per second and this node takes 5
+ // seconds to respond to each, the 5th ping the remote sends would appear to
+ // return very quickly.
+ pfrom->PushMessage("pong", nonce);
+ }
}
}
pto->fPingQueued = false;
pto->nPingUsecStart = GetTimeMicros();
- pto->nPingNonceSent = nonce;
- pto->PushMessage("ping", nonce);
+ if (pto->nVersion > BIP0031_VERSION) {
+ pto->nPingNonceSent = nonce;
+ pto->PushMessage("ping", nonce);
+ } else {
+ // Peer is too old to support ping command with nonce, pong will never arrive.
+ pto->nPingNonceSent = 0;
+ pto->PushMessage("ping");
+ }
}
TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()