forked from Bitcoin-ABC/bitcoin-abc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpolicy.cpp
176 lines (151 loc) · 5.78 KB
/
policy.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// NOTE: This file is intended to be customised by the end user, and includes
// only local node policy logic
#include <coins.h>
#include <policy/policy.h>
#include <script/interpreter.h>
#include <util/system.h>
Amount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn) {
/**
* "Dust" is defined in terms of dustRelayFee, which has units
* satoshis-per-kilobyte. If you'd pay more than 1/3 in fees to spend
* something, then we consider it dust. A typical spendable txout is 34
* bytes big, and will need a CTxIn of at least 148 bytes to spend: so dust
* is a spendable txout less than 546*dustRelayFee/1000 (in satoshis).
*/
if (txout.scriptPubKey.IsUnspendable()) {
return Amount::zero();
}
size_t nSize = GetSerializeSize(txout);
// the 148 mentioned above
nSize += (32 + 4 + 1 + 107 + 4);
return 3 * dustRelayFeeIn.GetFee(nSize);
}
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn) {
return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
}
bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType) {
std::vector<std::vector<uint8_t>> vSolutions;
whichType = Solver(scriptPubKey, vSolutions);
if (whichType == TX_NONSTANDARD) {
return false;
} else if (whichType == TX_MULTISIG) {
uint8_t m = vSolutions.front()[0];
uint8_t n = vSolutions.back()[0];
// Support up to x-of-3 multisig txns as standard
if (n < 1 || n > 3) {
return false;
}
if (m < 1 || m > n) {
return false;
}
} else if (whichType == TX_NULL_DATA) {
if (!fAcceptDatacarrier) {
return false;
}
unsigned nMaxDatacarrierBytes =
gArgs.GetArg("-datacarriersize", MAX_OP_RETURN_RELAY);
if (scriptPubKey.size() > nMaxDatacarrierBytes) {
return false;
}
}
return true;
}
bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig,
const CFeeRate &dust_relay_fee, std::string &reason) {
if (tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) {
reason = "version";
return false;
}
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
// to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
uint32_t sz = tx.GetTotalSize();
if (sz > MAX_STANDARD_TX_SIZE) {
reason = "tx-size";
return false;
}
for (const CTxIn &txin : tx.vin) {
if (txin.scriptSig.size() > MAX_TX_IN_SCRIPT_SIG_SIZE) {
reason = "scriptsig-size";
return false;
}
if (!txin.scriptSig.IsPushOnly()) {
reason = "scriptsig-not-pushonly";
return false;
}
}
unsigned int nDataOut = 0;
txnouttype whichType;
for (const CTxOut &txout : tx.vout) {
if (!::IsStandard(txout.scriptPubKey, whichType)) {
reason = "scriptpubkey";
return false;
}
if (whichType == TX_NULL_DATA) {
nDataOut++;
} else if ((whichType == TX_MULTISIG) && (!permit_bare_multisig)) {
reason = "bare-multisig";
return false;
} else if (IsDust(txout, dust_relay_fee)) {
reason = "dust";
return false;
}
}
// only one OP_RETURN txout is permitted
if (nDataOut > 1) {
reason = "multi-op-return";
return false;
}
return true;
}
/**
* Check transaction inputs to mitigate two
* potential denial-of-service attacks:
*
* 1. scriptSigs with extra data stuffed into them,
* not consumed by scriptPubKey (or P2SH script)
* 2. P2SH scripts with a crazy number of expensive
* CHECKSIG/CHECKMULTISIG operations
*
* Why bother? To avoid denial-of-service attacks; an attacker
* can submit a standard HASH... OP_EQUAL transaction,
* which will get accepted into blocks. The redemption
* script can be anything; an attacker could use a very
* expensive-to-check-upon-redemption script like:
* DUP CHECKSIG DROP ... repeated 100 times... OP_1
*/
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs,
uint32_t flags) {
if (tx.IsCoinBase()) {
// Coinbases don't use vin normally.
return true;
}
for (const CTxIn &in : tx.vin) {
const CTxOut &prev = mapInputs.AccessCoin(in.prevout).GetTxOut();
std::vector<std::vector<uint8_t>> vSolutions;
txnouttype whichType = Solver(prev.scriptPubKey, vSolutions);
if (whichType == TX_NONSTANDARD) {
return false;
}
}
return true;
}
int64_t GetVirtualTransactionSize(int64_t nSize, int64_t nSigOpCount,
unsigned int bytes_per_sigop) {
return std::max(nSize, nSigOpCount * bytes_per_sigop);
}
int64_t GetVirtualTransactionSize(const CTransaction &tx, int64_t nSigOpCount,
unsigned int bytes_per_sigop) {
return GetVirtualTransactionSize(::GetSerializeSize(tx, PROTOCOL_VERSION),
nSigOpCount, bytes_per_sigop);
}
int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCount,
unsigned int bytes_per_sigop) {
return GetVirtualTransactionSize(::GetSerializeSize(txin, PROTOCOL_VERSION),
nSigOpCount, bytes_per_sigop);
}