diff --git a/src/cryptonote_basic/verification_context.h b/src/cryptonote_basic/verification_context.h index 34157218f..ffd07b27a 100644 --- a/src/cryptonote_basic/verification_context.h +++ b/src/cryptonote_basic/verification_context.h @@ -53,6 +53,7 @@ namespace cryptonote bool m_overspend; bool m_fee_too_low; bool m_too_few_outputs; + bool m_tx_extra_too_big; }; struct block_verification_context diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 741f9ed3d..73650b8c1 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -217,6 +217,11 @@ #define DNS_BLOCKLIST_LIFETIME (86400 * 8) +//The limit is enough for the mandatory transaction content with 16 outputs (547 bytes), +//a custom tag (1 byte) and up to 32 bytes of custom data for each recipient. +// (1+32) + (1+1+16*32) + (1+16*32) = 1060 +#define MAX_TX_EXTRA_SIZE 1060 + // New constants are intended to go here namespace config { diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index b8172510f..8380d79b6 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -219,6 +219,15 @@ namespace cryptonote return false; } + size_t tx_extra_size = tx.extra.size(); + if (!kept_by_block && tx_extra_size > MAX_TX_EXTRA_SIZE) + { + LOG_PRINT_L1("transaction tx-extra is too big: " << tx_extra_size << " bytes, the limit is: " << MAX_TX_EXTRA_SIZE); + tvc.m_verifivation_failed = true; + tvc.m_tx_extra_too_big = true; + return false; + } + // if the transaction came from a block popped from the chain, // don't check if we have its key images as spent. // TODO: Investigate why not? diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index e036a21db..9cee51133 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1276,6 +1276,8 @@ namespace cryptonote add_reason(reason, "fee too low"); if ((res.too_few_outputs = tvc.m_too_few_outputs)) add_reason(reason, "too few outputs"); + if ((res.tx_extra_too_big = tvc.m_tx_extra_too_big)) + add_reason(reason, "tx-extra too big"); const std::string punctuation = reason.empty() ? "" : ": "; if (tvc.m_verifivation_failed) { diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 72f971174..d0e549649 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -88,7 +88,7 @@ namespace cryptonote // advance which version they will stop working with // Don't go over 32767 for any of these #define CORE_RPC_VERSION_MAJOR 3 -#define CORE_RPC_VERSION_MINOR 11 +#define CORE_RPC_VERSION_MINOR 12 #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) @@ -592,6 +592,7 @@ namespace cryptonote bool fee_too_low; bool too_few_outputs; bool sanity_check_failed; + bool tx_extra_too_big; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE_PARENT(rpc_access_response_base) @@ -606,6 +607,7 @@ namespace cryptonote KV_SERIALIZE(fee_too_low) KV_SERIALIZE(too_few_outputs) KV_SERIALIZE(sanity_check_failed) + KV_SERIALIZE(tx_extra_too_big) END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init response;