6767from chia .types .block_protocol import BlockInfo
6868from chia .types .blockchain_format .coin import Coin , hash_coin_ids
6969from chia .types .blockchain_format .proof_of_space import verify_and_get_quality_string
70+ from chia .types .clvm_cost import QUOTE_BYTES , QUOTE_EXECUTION_COST
7071from chia .types .generator_types import BlockGenerator , NewBlockGenerator
7172from chia .types .mempool_inclusion_status import MempoolInclusionStatus
7273from chia .types .peer_info import PeerInfo
@@ -220,11 +221,17 @@ async def new_transaction(
220221 # If already seen, the cost and fee must match, otherwise ban the peer
221222 mempool_item = self .full_node .mempool_manager .get_mempool_item (transaction .transaction_id , include_pending = True )
222223 if mempool_item is not None :
223- if mempool_item .cost != transaction .cost or mempool_item .fee != transaction .fees :
224+ # Older nodes (2.4.3 and earlier) compute the cost slightly
225+ # differently. They include the byte cost and execution cost of
226+ # the quote for the puzzle.
227+ tolerated_diff = QUOTE_BYTES * self .full_node .constants .COST_PER_BYTE + QUOTE_EXECUTION_COST
228+ if (transaction .cost != mempool_item .cost and transaction .cost != mempool_item .cost + tolerated_diff ) or (
229+ transaction .fees != mempool_item .fee
230+ ):
224231 self .log .warning (
225- f"Banning peer { peer .peer_node_id } . Sent us an already seen tx { transaction . transaction_id } "
226- f"with mismatch on cost { transaction .cost } vs validation cost { mempool_item . cost } and/or "
227- f"fee { transaction .fees } vs { mempool_item .fee } ."
232+ f"Banning peer { peer .peer_node_id } version { peer . version } . Sent us an already seen tx "
233+ f"{ transaction . transaction_id } with mismatch on cost { transaction .cost } vs validation "
234+ f"cost { mempool_item . cost } and/or fee { transaction .fees } vs { mempool_item .fee } ."
228235 )
229236 await peer .close (CONSENSUS_ERROR_BAN_SECONDS )
230237 return None
@@ -244,11 +251,19 @@ async def new_transaction(
244251 return None
245252 prev = current_map .get (peer .peer_node_id )
246253 if prev is not None :
247- if prev .advertised_fee != transaction .fees or prev .advertised_cost != transaction .cost :
254+ # Older nodes (2.4.3 and earlier) compute the cost slightly
255+ # differently. They include the byte cost and execution cost of
256+ # the quote for the puzzle.
257+ tolerated_diff = QUOTE_BYTES * self .full_node .constants .COST_PER_BYTE + QUOTE_EXECUTION_COST
258+ if prev .advertised_fee != transaction .fees or (
259+ prev .advertised_cost != transaction .cost
260+ and abs (prev .advertised_cost - transaction .cost ) != tolerated_diff
261+ ):
248262 self .log .warning (
249- f"Banning peer { peer .peer_node_id } . Sent us a new tx { transaction .transaction_id } with "
250- f"mismatch on cost { transaction .cost } vs previous advertised cost { prev .advertised_cost } "
251- f"and/or fee { transaction .fees } vs previous advertised fee { prev .advertised_fee } ."
263+ f"Banning peer { peer .peer_node_id } version { peer .version } . Sent us a new tx "
264+ f"{ transaction .transaction_id } with mismatch on cost { transaction .cost } vs "
265+ f"previous advertised cost { prev .advertised_cost } and/or fee { transaction .fees } "
266+ f"vs previous advertised fee { prev .advertised_fee } ."
252267 )
253268 await peer .close (CONSENSUS_ERROR_BAN_SECONDS )
254269 return None
0 commit comments