| 1103 | |
| 1104 | |
| 1105 | bool CheckTransaction(const CTransaction& tx, CValidationState &state) |
| 1106 | { |
| 1107 | // Basic checks that don't depend on any context |
| 1108 | if (tx.vin.empty()) |
| 1109 | return state.DoS(10, error("CheckTransaction(): vin empty"), |
| 1110 | REJECT_INVALID, "bad-txns-vin-empty"); |
| 1111 | if (tx.vout.empty()) |
| 1112 | return state.DoS(10, error("CheckTransaction(): vout empty"), |
| 1113 | REJECT_INVALID, "bad-txns-vout-empty"); |
| 1114 | // Size limits |
| 1115 | if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TRANSACTION_SIZE) |
| 1116 | return state.DoS(100, error("CheckTransaction(): size limits failed"), |
| 1117 | REJECT_INVALID, "bad-txns-oversize"); |
| 1118 | |
| 1119 | // Check for negative or overflow output values |
| 1120 | CAmount nValueOut = 0; |
| 1121 | BOOST_FOREACH(const CTxOut& txout, tx.vout) |
| 1122 | { |
| 1123 | if (txout.nValue < 0) |
| 1124 | return state.DoS(100, error("CheckTransaction(): txout.nValue negative"), |
| 1125 | REJECT_INVALID, "bad-txns-vout-negative"); |
| 1126 | if (txout.nValue > MAX_MONEY) |
| 1127 | return state.DoS(100, error("CheckTransaction(): txout.nValue too high"), |
| 1128 | REJECT_INVALID, "bad-txns-vout-toolarge"); |
| 1129 | nValueOut += txout.nValue; |
| 1130 | if (!MoneyRange(nValueOut)) |
| 1131 | return state.DoS(100, error("CheckTransaction(): txout total out of range"), |
| 1132 | REJECT_INVALID, "bad-txns-txouttotal-toolarge"); |
| 1133 | } |
| 1134 | |
| 1135 | if (GetLegacySigOpCount(tx) > MAX_TX_SIGOPS_COUNT) { |
| 1136 | return state.DoS(100, error("CheckTransaction(): too many sigops in tx"), REJECT_INVALID, "bad-txn-sigops"); |
| 1137 | } |
| 1138 | |
| 1139 | // Check for duplicate inputs |
| 1140 | set<COutPoint> vInOutPoints; |
| 1141 | BOOST_FOREACH(const CTxIn& txin, tx.vin) |
| 1142 | { |
| 1143 | if (vInOutPoints.count(txin.prevout)) |
| 1144 | return state.DoS(100, error("CheckTransaction(): duplicate inputs"), |
| 1145 | REJECT_INVALID, "bad-txns-inputs-duplicate"); |
| 1146 | vInOutPoints.insert(txin.prevout); |
| 1147 | } |
| 1148 | |
| 1149 | if (tx.IsCoinBase()) |
| 1150 | { |
| 1151 | if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) |
| 1152 | return state.DoS(100, error("CheckTransaction(): coinbase script size"), |
| 1153 | REJECT_INVALID, "bad-cb-length"); |
| 1154 | } |
| 1155 | else |
| 1156 | { |
| 1157 | BOOST_FOREACH(const CTxIn& txin, tx.vin) |
| 1158 | if (txin.prevout.IsNull()) |
| 1159 | return state.DoS(10, error("CheckTransaction(): prevout is null"), |
| 1160 | REJECT_INVALID, "bad-txns-prevout-null"); |
| 1161 | } |
| 1162 | |