except JSONRPCException,e:
errorString = e.error['message']
assert_equal("Invalid parameter, expiryheight must be nonnegative and less than 500000000" in errorString, True)
+ try:
+ self.nodes[0].createrawtransaction([], {}, 0, 200)
+ except JSONRPCException,e:
+ errorString = e.error['message']
+ assert_equal("Invalid parameter, expiryheight should be at least 203 to avoid transaction expiring soon" in errorString, True)
# Node 0 sends transparent funds to Node 3
tsendamount = Decimal('1.0')
" ,...\n"
" }\n"
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
- "4. expiryheight (numeric, optional, default=" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction (if Overwinter is active)\n"
+ "4. expiryheight (numeric, optional, default=nextblockheight+" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction (if Overwinter is active)\n"
"\nResult:\n"
"\"transaction\" (string) hex string of the transaction\n"
if (nExpiryHeight < 0 || nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, expiryheight must be nonnegative and less than %d.", TX_EXPIRY_HEIGHT_THRESHOLD));
}
+ // DoS mitigation: reject transactions expiring soon
+ if (nextBlockHeight + TX_EXPIRING_SOON_THRESHOLD > nExpiryHeight) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER,
+ strprintf("Invalid parameter, expiryheight should be at least %d to avoid transaction expiring soon",
+ nextBlockHeight + TX_EXPIRING_SOON_THRESHOLD));
+ }
rawTx.nExpiryHeight = nExpiryHeight;
} else {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expiryheight can only be used if Overwinter is active when the transaction is mined");