|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# Copyright (c) 2025 The Dash Core developers |
| 3 | +# Distributed under the MIT software license, see the accompanying |
| 4 | +# file COPYING or http://www.opensource.org/licenses/mit-license.php. |
| 5 | + |
| 6 | +from test_framework.messages import msg_platformban, hash256, ser_string, ser_uint256 |
| 7 | +from test_framework.p2p import ( |
| 8 | + p2p_lock, |
| 9 | + P2PInterface, |
| 10 | +) |
| 11 | +from test_framework.test_framework import DashTestFramework |
| 12 | +from test_framework.util import wait_until_helper |
| 13 | + |
| 14 | +import struct |
| 15 | + |
| 16 | +class PlatformBanInterface(P2PInterface): |
| 17 | + def __init__(self): |
| 18 | + super().__init__() |
| 19 | + |
| 20 | + |
| 21 | +class PlatformBanMessagesTest(DashTestFramework): |
| 22 | + def set_test_params(self): |
| 23 | + self.set_dash_test_params(1, 0, [[]], evo_count=3) |
| 24 | + |
| 25 | + def skip_test_if_missing_module(self): |
| 26 | + self.skip_if_no_wallet() |
| 27 | + |
| 28 | + def check_banned(self, mn): |
| 29 | + info = self.nodes[0].protx('info', mn.proTxHash) |
| 30 | + return info['state']['PoSeBanHeight'] != -1 |
| 31 | + |
| 32 | + def run_test(self): |
| 33 | + node = self.nodes[0] |
| 34 | + |
| 35 | + node.sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0) |
| 36 | + node.sporkupdate("SPORK_23_QUORUM_POSE", 0) |
| 37 | + self.wait_for_sporks_same() |
| 38 | + |
| 39 | + evo_info_0 = self.dynamically_add_masternode(evo=True) |
| 40 | + for _ in range(2): |
| 41 | + self.dynamically_add_masternode(evo=True) |
| 42 | + |
| 43 | + self.mempool_size = 0 |
| 44 | + |
| 45 | + self.mine_quorum(llmq_type_name='llmq_test_platform', llmq_type=106) |
| 46 | + |
| 47 | + self.log.info("Create and sign platform-ban message for mn-0") |
| 48 | + msg = msg_platformban() |
| 49 | + msg.protx_hash = int(self.mninfo[0].proTxHash, 16) |
| 50 | + msg.requested_height = node.getblockcount() |
| 51 | + |
| 52 | + request_id_buf = ser_string(b"PlatformPoSeBan") + ser_uint256(msg.protx_hash) + struct.pack("<I", msg.requested_height) |
| 53 | + request_id = hash256(request_id_buf)[::-1].hex() |
| 54 | + |
| 55 | + quorum_hash = self.mninfo[1].node.quorum("selectquorum", 106, request_id)["quorumHash"] |
| 56 | + msg.quorum_hash = int(quorum_hash, 16) |
| 57 | + |
| 58 | + msg_hash = format(msg.calc_sha256(), '064x') |
| 59 | + |
| 60 | + recsig = self.get_recovered_sig(request_id, msg_hash, llmq_type=106, use_platformsign=True) |
| 61 | + msg.sig = bytearray.fromhex(recsig["sig"]) |
| 62 | + |
| 63 | + self.log.info("Platform ban message is created and signed") |
| 64 | + p2p_node2 = self.mninfo[2].node.add_p2p_connection(PlatformBanInterface()) |
| 65 | + p2p_node2.send_message(msg) |
| 66 | + wait_until_helper(lambda: p2p_node2.message_count["platformban"] > 0, timeout=10, lock=p2p_lock) |
| 67 | + p2p_node2.message_count["platformban"] = 0 |
| 68 | + |
| 69 | + |
| 70 | + assert not self.check_banned(self.mninfo[0]) |
| 71 | + |
| 72 | + self.mine_quorum(llmq_type_name='llmq_test_platform', expected_members=2, expected_connections=1, expected_contributions=2, expected_commitments=2, llmq_type=106) |
| 73 | + |
| 74 | + p2p_node = node.add_p2p_connection(PlatformBanInterface()) |
| 75 | + p2p_node.send_message(msg) |
| 76 | + self.mine_quorum(llmq_type_name='llmq_test_platform', expected_members=2, expected_connections=1, expected_contributions=2, expected_commitments=2, llmq_type=106) |
| 77 | + assert self.check_banned(self.mninfo[0]) |
| 78 | + |
| 79 | + self.dynamically_evo_update_service(evo_info_0) |
| 80 | + assert not self.check_banned(self.mninfo[0]) |
| 81 | + |
| 82 | +if __name__ == '__main__': |
| 83 | + PlatformBanMessagesTest().main() |
0 commit comments