1#!/usr/bin/env python3 2 3from test_framework.test_framework import BitcoinTestFramework 4from test_framework.util import * 5from test_framework.script import * 6from test_framework.mininode import * 7from test_framework.address import * 8from test_framework.qtum import * 9 10class QtumDivergenceDosTest(BitcoinTestFramework): 11 def set_test_params(self): 12 self.setup_clean_chain = True 13 self.num_nodes = 1 14 self.extra_args = [[]] 15 16 def skip_test_if_missing_module(self): 17 self.skip_if_no_wallet() 18 19 def submit_block_with_txs(self, txs): 20 tip = self.node.getblock(self.node.getbestblockhash()) 21 block = create_block(int(tip['hash'], 16), create_coinbase(tip['height']+1), tip['time']+1) 22 block.hashStateRoot = int(tip['hashStateRoot'], 16) 23 block.hashUTXORoot = int(tip['hashUTXORoot'], 16) 24 if txs: 25 address = self.node.gettxout(hex(txs[0].vin[0].prevout.hash)[2:].zfill(64), txs[0].vin[0].prevout.n)['scriptPubKey']['addresses'][0] 26 haddress = hex_str_to_bytes(p2pkh_to_hex_hash(address)) 27 block.vtx[0].vout.append(CTxOut(100, CScript([OP_DUP, OP_HASH160, haddress, OP_EQUALVERIFY, OP_CHECKSIG]))) 28 if len(txs) > 1: 29 txs[-1].vout[0].scriptPubKey = CScript([OP_DUP, OP_HASH160, haddress, OP_EQUALVERIFY, OP_CHECKSIG]) 30 31 block.vtx += txs 32 for tx in block.vtx: 33 tx.rehash() 34 block.hashMerkleRoot = block.calc_merkle_root() 35 block.solve() 36 assert_equal(self.node.submitblock(bytes_to_hex_str(block.serialize())), 'incorrect-transactions-or-hashes-block') 37 38 39 def too_few_txs_test(self): 40 # Run it many times so we can trigger out of bounds segfaults with a high probability 41 tx = CTransaction() 42 tx.vin = [make_vin(self.node, COIN)] 43 tx.vout = [CTxOut(COIN-40000000, scriptPubKey=CScript([b"\x04", CScriptNum(100000), CScriptNum(QTUM_MIN_GAS_PRICE), hex_str_to_bytes("00"), hex_str_to_bytes(self.contract_address), OP_CALL]))] 44 tx = rpc_sign_transaction(self.node, tx) 45 tx.rehash() 46 self.submit_block_with_txs([tx]) 47 48 def different_but_same_number_aal_txs_test(self): 49 # Run it many times so we can trigger out of bounds segfaults with a high probability 50 tx1 = CTransaction() 51 tx1.vin = [make_vin(self.node, COIN // 10)] 52 tx1.vout = [CTxOut(1, scriptPubKey=CScript([b"\x04", CScriptNum(100000), CScriptNum(QTUM_MIN_GAS_PRICE), hex_str_to_bytes("00"), hex_str_to_bytes(self.contract_address), OP_CALL]))] 53 tx1 = rpc_sign_transaction(self.node, tx1) 54 tx1.rehash() 55 56 tx2 = CTransaction() 57 tx2.nVersion = 2 58 tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), scriptSig=CScript([OP_SPEND]), nSequence=0xffffffff)] 59 tx2.vout = [CTxOut(0, scriptPubKey=CScript([OP_DUP, OP_HASH160, hex_str_to_bytes("00"*19)+b"\x01", OP_EQUALVERIFY, OP_CHECKSIG]))] 60 tx2.rehash() 61 self.submit_block_with_txs([tx1, tx2]) 62 63 64 def too_many_txs_test(self): 65 # Run it many times so we can trigger out of bounds segfaults with a high probability 66 tx1 = CTransaction() 67 tx1.vin = [make_vin(self.node, COIN // 10)] 68 tx1.vout = [CTxOut(1, scriptPubKey=CScript([b"\x04", CScriptNum(100000), CScriptNum(QTUM_MIN_GAS_PRICE), hex_str_to_bytes("00"), hex_str_to_bytes(self.contract_address), OP_CALL]))] 69 tx1 = rpc_sign_transaction(self.node, tx1) 70 tx1.rehash() 71 72 tx2 = CTransaction() 73 tx2.nVersion = 2 74 tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), scriptSig=CScript([OP_SPEND]), nSequence=0xffffffff)] 75 tx2.vout = [CTxOut(0, scriptPubKey=CScript([b"\x00", CScriptNum(0), CScriptNum(0), hex_str_to_bytes("00"), hex_str_to_bytes(self.contract_address), OP_CALL]))] 76 tx2.rehash() 77 78 tx3 = CTransaction() 79 tx2.nVersion = 2 80 tx3.vin = [CTxIn(COutPoint(tx2.sha256, 0), scriptSig=CScript([OP_SPEND]))] 81 tx3.vout = [CTxOut(0, scriptPubKey=CScript([OP_DUP, OP_HASH160, hex_str_to_bytes("00"*19)+b"\x00", OP_EQUALVERIFY, OP_CHECKSIG]))] 82 tx3.rehash() 83 self.submit_block_with_txs([tx1, tx2, tx3]) 84 85 def run_test(self): 86 self.node = self.nodes[0] 87 self.node.generate(500+COINBASE_MATURITY) 88 """ 89 pragma solidity ^0.4.24; 90 contract Ballot { 91 function() payable public { 92 while(true){} 93 } 94 } 95 """ 96 bytecode = "6080604052348015600f57600080fd5b50603d80601d6000396000f30060806040525b600115600f576005565b0000a165627a7a72305820046fe704d7206dd7bd828449504709b4786e72b5b8cb47633add96fec4d343410029" 97 self.contract_address = self.node.createcontract(bytecode)['address'] 98 self.node.generate(1) 99 self.too_few_txs_test() 100 self.different_but_same_number_aal_txs_test() 101 self.too_many_txs_test() 102 103if __name__ == '__main__': 104 QtumDivergenceDosTest().main() 105