def _zmq_test(self): num_blocks = 5 self.log.info("Generate %(n)d blocks (and %(n)d coinbase txes)" % {"n": num_blocks}) genhashes = self.nodes[0].generatetoaddress(num_blocks, ADDRESS_BCRT1_UNSPENDABLE) self.sync_all() for x in range(num_blocks): # Should receive the coinbase txid. txid = self.hashtx.receive() # Should receive the coinbase raw transaction. hex = self.rawtx.receive() tx = CTransaction() tx.deserialize(BytesIO(hex)) tx.calc_sha256() assert_equal(tx.hash, txid.hex()) # Should receive the generated block hash. hash = self.hashblock.receive().hex() assert_equal(genhashes[x], hash) # The block should only have the coinbase txid. assert_equal([txid.hex()], self.nodes[1].getblock(hash)["tx"]) # Should receive the generated raw block. block = self.rawblock.receive() assert_equal(genhashes[x], hash256(block[:80]).hex()) if self.is_wallet_compiled(): self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, txid.hex()) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, hash256(hex).hex()) self.log.info("Test the getzmqnotifications RPC") assert_equal(self.nodes[0].getzmqnotifications(), [ {"type": "pubhashblock", "address": ADDRESS, "hwm": 1000}, {"type": "pubhashtx", "address": ADDRESS, "hwm": 1000}, {"type": "pubrawblock", "address": ADDRESS, "hwm": 1000}, {"type": "pubrawtx", "address": ADDRESS, "hwm": 1000}, ]) assert_equal(self.nodes[1].getzmqnotifications(), [])
def _zmq_test(self): num_blocks = 5 self.log.info("Generate %(n)d blocks (and %(n)d coinbase txes)" % {"n": num_blocks}) genhashes = self.nodes[0].generate(num_blocks) self.sync_all() for x in range(num_blocks): # Should receive the coinbase txid. txid = self.hashtx.receive() # Should receive the coinbase raw transaction. hex = self.rawtx.receive() assert_equal( bytes_to_hex_str(hash256(hex)), self.nodes[1].getrawtransaction(bytes_to_hex_str(txid), True)["hash"]) # Should receive the generated block hash. hash = bytes_to_hex_str(self.hashblock.receive()) assert_equal(genhashes[x], hash) # The block should only have the coinbase txid. assert_equal([bytes_to_hex_str(txid)], self.nodes[1].getblock(hash)["tx"]) # Should receive the generated raw block. block = self.rawblock.receive() assert_equal(genhashes[x], hash_block(bytes_to_hex_str(block[:80]))) self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress( self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, bytes_to_hex_str(txid)) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, bytes_to_hex_str(hash256(hex)))
def _zmq_test(self): num_blocks = 5 self.log.info("Generate %(n)d blocks (and %(n)d coinbase txes)" % {"n": num_blocks}) genhashes = self.nodes[0].generatetoaddress(num_blocks, ADDRESS_BCRT1_UNSPENDABLE) self.sync_all() for x in range(num_blocks): # Should receive the coinbase txid. txid = self.hashtx.receive() # Should receive the coinbase raw transaction. hex = self.rawtx.receive() tx = CTransaction() tx.deserialize(BytesIO(hex)) tx.calc_sha256() assert_equal(tx.hash, bytes_to_hex_str(txid)) # Should receive the generated block hash. hash = bytes_to_hex_str(self.hashblock.receive()) assert_equal(genhashes[x], hash) # The block should only have the coinbase txid. assert_equal([bytes_to_hex_str(txid)], self.nodes[1].getblock(hash)["tx"]) # Should receive the generated raw block. raw_block = self.rawblock.receive() block = CBlock() f = BytesIO(raw_block) block.deserialize(f) block.calc_sha256() assert_equal(genhashes[x], block.hash) if self.is_wallet_compiled(): self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, bytes_to_hex_str(txid)) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, bytes_to_hex_str(hash256(hex))) self.log.info("Test the getzmqnotifications RPC") assert_equal(self.nodes[0].getzmqnotifications(), [ {"type": "pubhashblock", "address": ADDRESS, "hwm": 1000}, {"type": "pubhashtx", "address": ADDRESS, "hwm": 1000}, {"type": "pubrawblock", "address": ADDRESS, "hwm": 1000}, {"type": "pubrawtx", "address": ADDRESS, "hwm": 1000}, ]) assert_equal(self.nodes[1].getzmqnotifications(), [])
def _zmq_test(self): num_blocks = 5 self.log.info( "Generate {0} blocks (and {0} coinbase txes)".format(num_blocks)) genhashes = self.nodes[0].generate(num_blocks) self.sync_all() for x in range(num_blocks): # Should receive the coinbase txid. txid = self.hashtx.receive() # Should receive the coinbase raw transaction. hex = self.rawtx.receive() tx = CTransaction() tx.deserialize(BytesIO(hex)) tx.calc_sha256() assert_equal(tx.hash, bytes_to_hex_str(txid)) # Should receive the generated block hash. hash = bytes_to_hex_str(self.hashblock.receive()) assert_equal(genhashes[x], hash) # The block should only have the coinbase txid. assert_equal([bytes_to_hex_str(txid)], self.nodes[1].getblock(hash)["tx"]) # Should receive the generated raw block. block = self.rawblock.receive() assert_equal(genhashes[x], bytes_to_hex_str(hash256(block[:80]))) self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress( self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, bytes_to_hex_str(txid)) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, bytes_to_hex_str(hash256(hex)))
def _zmq_test(self): num_blocks = 5 self.log.info("Generate %(n)d blocks (and %(n)d coinbase txes)" % {"n": num_blocks}) genhashes = self.nodes[0].generate(num_blocks) self.sync_all() for x in range(num_blocks): # Should receive the coinbase txid. txid = self.hashtx.receive() # Should receive the coinbase raw transaction. hex = self.rawtx.receive() tx = CTransaction() tx.deserialize(BytesIO(hex)) tx.calc_sha256() assert_equal(tx.hash, bytes_to_hex_str(txid)) # Should receive the generated block hash. hash = bytes_to_hex_str(self.hashblock.receive()) assert_equal(genhashes[x], hash) # The block should only have the coinbase txid. assert_equal([bytes_to_hex_str(txid)], self.nodes[1].getblock(hash)["tx"]) # Should receive the generated raw block. block = self.rawblock.receive() # 79 bytes, last byte is saying block solution is "", ellide this for hash assert_equal(genhashes[x], bytes_to_hex_str(hash256(block[:78]))) self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, bytes_to_hex_str(txid)) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, bytes_to_hex_str(hash256(hex)))
def check_txnotification(self, seq): self.log.info("Wait for tx") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx2") txhash = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, seq) msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawtx2") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, seq) # Check that the rawtx hashes to the hashtx assert_equal(hash256(body), txhash) return bytes_to_hex_str(txhash)
def sign_stake_tx(self, block, stake_in_value, fZPoS=False): ''' signs a coinstake transaction :param block: (CBlock) block with stake to sign stake_in_value: (int) staked amount fZPoS: (bool) zerocoin stake :return: stake_tx_signed: (CTransaction) signed tx ''' self.block_sig_key = CECKey() if fZPoS: self.log.info("Signing zPoS stake...") # Create raw zerocoin stake TX (signed) raw_stake = self.node.createrawzerocoinstake(block.prevoutStake) stake_tx_signed_raw_hex = raw_stake["hex"] # Get stake TX private key to sign the block with stake_pkey = raw_stake["private-key"] self.block_sig_key.set_compressed(True) self.block_sig_key.set_secretbytes(bytes.fromhex(stake_pkey)) else: # Create a new private key and get the corresponding public key self.block_sig_key.set_secretbytes(hash256(pack('<I', 0xffff))) pubkey = self.block_sig_key.get_pubkey() # Create the raw stake TX (unsigned) scriptPubKey = CScript([pubkey, OP_CHECKSIG]) outNValue = int(stake_in_value + 2 * COIN) stake_tx_unsigned = CTransaction() stake_tx_unsigned.nTime = block.nTime stake_tx_unsigned.vin.append(CTxIn(block.prevoutStake)) stake_tx_unsigned.vin[0].nSequence = 0xffffffff stake_tx_unsigned.vout.append(CTxOut()) stake_tx_unsigned.vout.append(CTxOut(outNValue, scriptPubKey)) # Sign the stake TX stake_tx_signed_raw_hex = self.node.signrawtransaction( bytes_to_hex_str(stake_tx_unsigned.serialize()))['hex'] # Deserialize the signed raw tx into a CTransaction object and return it stake_tx_signed = CTransaction() stake_tx_signed.deserialize( BytesIO(hex_str_to_bytes(stake_tx_signed_raw_hex))) return stake_tx_signed
def check_blocknotification(self, blockhash, seq): self.log.info("Wait for block") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashblock2") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, seq) blkhash = bytes_to_hex_str(body) # blockhash from generate must be equal to the hash received over zmq assert_equal(blockhash, blkhash) msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawblock2") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, seq) # Check the hash of the rawblock's header matches generate assert_equal(blockhash, bytes_to_hex_str(hash256(body[:80])))
def sign_stake_tx(self, block, stake_in_value, fZPoS=False): ''' signs a coinstake transaction :param block: (CBlock) block with stake to sign stake_in_value: (int) staked amount fZPoS: (bool) zerocoin stake :return: stake_tx_signed: (CTransaction) signed tx ''' self.block_sig_key = CECKey() if fZPoS: self.log.info("Signing zPoS stake...") # Create raw zerocoin stake TX (signed) raw_stake = self.node.createrawzerocoinstake(block.prevoutStake) stake_tx_signed_raw_hex = raw_stake["hex"] # Get stake TX private key to sign the block with stake_pkey = raw_stake["private-key"] self.block_sig_key.set_compressed(True) self.block_sig_key.set_secretbytes(bytes.fromhex(stake_pkey)) else: # Create a new private key and get the corresponding public key self.block_sig_key.set_secretbytes(hash256(pack('<I', 0xffff))) pubkey = self.block_sig_key.get_pubkey() # Create the raw stake TX (unsigned) scriptPubKey = CScript([pubkey, OP_CHECKSIG]) outNValue = int(stake_in_value + 2*COIN) stake_tx_unsigned = CTransaction() stake_tx_unsigned.nTime = block.nTime stake_tx_unsigned.vin.append(CTxIn(block.prevoutStake)) stake_tx_unsigned.vin[0].nSequence = 0xffffffff stake_tx_unsigned.vout.append(CTxOut()) stake_tx_unsigned.vout.append(CTxOut(outNValue, scriptPubKey)) # Sign the stake TX stake_tx_signed_raw_hex = self.node.signrawtransaction(bytes_to_hex_str(stake_tx_unsigned.serialize()))['hex'] # Deserialize the signed raw tx into a CTransaction object and return it stake_tx_signed = CTransaction() stake_tx_signed.deserialize(BytesIO(hex_str_to_bytes(stake_tx_signed_raw_hex))) return stake_tx_signed
def _zmq_test(self): genhashes = self.nodes[0].generate(1) self.sync_all() self.log.info("Wait for tx") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx") txhash = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on hashtx # rawtx msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawtx") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on rawtx # Check that the rawtx hashes to the hashtx assert_equal(hash256(body), txhash) self.log.info("Wait for block") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashblock") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on hashblock blkhash = bytes_to_hex_str(body) assert_equal( genhashes[0], blkhash ) # blockhash from generate must be equal to the hash received over zmq # rawblock msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawblock") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) #must be sequence 0 on rawblock # Check the hash of the rawblock's header matches generate assert_equal(genhashes[0], dftzhash_helper(body[:80])) self.log.info("Generate 10 blocks (and 10 coinbase txes)") n = 10 genhashes = self.nodes[1].generate(n) self.sync_all() zmqHashes = [] zmqRawHashed = [] blockcount = 0 for x in range(n * 4): msg = self.zmqSubSocket.recv_multipart() topic = msg[0] body = msg[1] if topic == b"hashblock": zmqHashes.append(bytes_to_hex_str(body)) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount + 1) blockcount += 1 if topic == b"rawblock": zmqRawHashed.append(dftzhash_helper(body[:80])) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount) for x in range(n): assert_equal( genhashes[x], zmqHashes[x] ) # blockhash from generate must be equal to the hash received over zmq assert_equal(genhashes[x], zmqRawHashed[x]) self.log.info("Wait for tx from second node") # test tx from a second node hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx") body = msg[1] hashZMQ = bytes_to_hex_str(body) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount + 1) msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawtx") body = msg[1] hashedZMQ = bytes_to_hex_str(hash256(body)) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount + 1) assert_equal( hashRPC, hashZMQ ) # txid from sendtoaddress must be equal to the hash received over zmq assert_equal(hashRPC, hashedZMQ)
def create_block(self, prev_hash, staking_prevouts, height, node_n, s_address, fInvalid=0): api = self.nodes[node_n] # Get current time current_time = int(time.time()) nTime = current_time & 0xfffffff0 # Create coinbase TX coinbase = create_coinbase(height) coinbase.vout[0].nValue = 0 coinbase.vout[0].scriptPubKey = b"" coinbase.nTime = nTime coinbase.rehash() # Create Block with coinbase block = create_block(int(prev_hash, 16), coinbase, nTime) # Find valid kernel hash - Create a new private key used for block signing. if not block.solve_stake(staking_prevouts): raise Exception("Not able to solve for any prev_outpoint") # Create coinstake TX amount, prev_time, prevScript = staking_prevouts[block.prevoutStake] outNValue = int(amount + 250 * COIN) stake_tx_unsigned = CTransaction() stake_tx_unsigned.nTime = block.nTime stake_tx_unsigned.vin.append(CTxIn(block.prevoutStake)) stake_tx_unsigned.vin[0].nSequence = 0xffffffff stake_tx_unsigned.vout.append(CTxOut()) stake_tx_unsigned.vout.append( CTxOut(outNValue, hex_str_to_bytes(prevScript))) if fInvalid == 1: # Create a new private key and get the corresponding public key block_sig_key = CECKey() block_sig_key.set_secretbytes(hash256(pack('<I', 0xffff))) pubkey = block_sig_key.get_pubkey() stake_tx_unsigned.vout[1].scriptPubKey = CScript( [pubkey, OP_CHECKSIG]) else: # Export the staking private key to sign the block with it privKey, compressed = wif_to_privkey(api.dumpprivkey(s_address)) block_sig_key = CECKey() block_sig_key.set_compressed(compressed) block_sig_key.set_secretbytes(bytes.fromhex(privKey)) # check the address addy = key_to_p2pkh(bytes_to_hex_str(block_sig_key.get_pubkey()), False, True) assert (addy == s_address) if fInvalid == 2: # add a new output with 100 coins from the pot new_key = CECKey() new_key.set_secretbytes(hash256(pack('<I', 0xffff))) pubkey = new_key.get_pubkey() stake_tx_unsigned.vout.append( CTxOut(100 * COIN, CScript([pubkey, OP_CHECKSIG]))) stake_tx_unsigned.vout[1].nValue = outNValue - 100 * COIN # Sign coinstake TX and add it to the block stake_tx_signed_raw_hex = api.signrawtransaction( bytes_to_hex_str(stake_tx_unsigned.serialize()))['hex'] stake_tx_signed = CTransaction() stake_tx_signed.deserialize( BytesIO(hex_str_to_bytes(stake_tx_signed_raw_hex))) block.vtx.append(stake_tx_signed) # Get correct MerkleRoot and rehash block block.hashMerkleRoot = block.calc_merkle_root() block.rehash() # sign block with block signing key and return it block.sign_block(block_sig_key) return block
def _zmq_test(self): genhashes = self.nodes[0].generate(1) self.sync_all() self.log.info("Wait for tx") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx") txhash = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on hashtx # rawtx msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawtx") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on rawtx # Check that the rawtx hashes to the hashtx assert_equal(hash256(body), txhash) self.log.info("Wait for block") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashblock") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on hashblock blkhash = bytes_to_hex_str(body) # blockhash from generate must be equal to the hash received over zmq assert_equal(genhashes[0], blkhash) # rawblock msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawblock") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on rawblock # Check the hash of the rawblock's header matches generate assert_equal(genhashes[0], bytes_to_hex_str(hash256(body[:80]))) self.log.info("Generate 10 blocks (and 10 coinbase txes)") n = 10 genhashes = self.nodes[1].generate(n) self.sync_all() zmqHashes = [] zmqRawHashed = [] blockcount = 0 for x in range(n * 4): msg = self.zmqSubSocket.recv_multipart() topic = msg[0] body = msg[1] if topic == b"hashblock": zmqHashes.append(bytes_to_hex_str(body)) msgSequence = struct.unpack('<I', msg[-1])[-1] blockcount += 1 if topic == b"rawblock": zmqRawHashed.append(bytes_to_hex_str(hash256(body[:80]))) msgSequence = struct.unpack('<I', msg[-1])[-1] # All blocks should trigger messages but they can be interleaved meaning # we receive hashblock message for block 3 while we still havent received # rawblock message for block 2. # For that reason we just check that we got all the messages and not their # order. assert_equal(len(zmqHashes), n) assert_equal(len(zmqRawHashed), n) # blockhash from generate must be equal to the hash received over zmq assert_equal(set(genhashes), set(zmqHashes)) assert_equal(set(genhashes), set(zmqRawHashed)) self.log.info("Wait for tx from second node") # test tx from a second node hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx") body = msg[1] hashZMQ = bytes_to_hex_str(body) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount + 1) msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawtx") body = msg[1] hashedZMQ = bytes_to_hex_str(hash256(body)) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount + 1) # txid from sendtoaddress must be equal to the hash received over zmq assert_equal(hashRPC, hashZMQ) assert_equal(hashRPC, hashedZMQ)
def _zmq_test(self): genhashes = self.nodes[0].generate(1) self.sync_all() self.log.info("Wait for tx") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx") txhash = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on hashtx # rawtx msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawtx") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on rawtx # Check that the rawtx hashes to the hashtx assert_equal(hash256(body), txhash) self.log.info("Wait for block") msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashblock") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) # must be sequence 0 on hashblock blkhash = bytes_to_hex_str(body) assert_equal(genhashes[0], blkhash) # blockhash from generate must be equal to the hash received over zmq # rawblock msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawblock") body = msg[1] msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, 0) #must be sequence 0 on rawblock # Check the hash of the rawblock's header matches generate assert_equal(genhashes[0], bytes_to_hex_str(hash256(body[:80]))) self.log.info("Generate 10 blocks (and 10 coinbase txes)") n = 10 genhashes = self.nodes[1].generate(n) self.sync_all() zmqHashes = [] zmqRawHashed = [] blockcount = 0 for x in range(n * 4): msg = self.zmqSubSocket.recv_multipart() topic = msg[0] body = msg[1] if topic == b"hashblock": zmqHashes.append(bytes_to_hex_str(body)) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount + 1) blockcount += 1 if topic == b"rawblock": zmqRawHashed.append(bytes_to_hex_str(hash256(body[:80]))) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount) for x in range(n): assert_equal(genhashes[x], zmqHashes[x]) # blockhash from generate must be equal to the hash received over zmq assert_equal(genhashes[x], zmqRawHashed[x]) self.log.info("Wait for tx from second node") # test tx from a second node hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"hashtx") body = msg[1] hashZMQ = bytes_to_hex_str(body) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount + 1) msg = self.zmqSubSocket.recv_multipart() topic = msg[0] assert_equal(topic, b"rawtx") body = msg[1] hashedZMQ = bytes_to_hex_str(hash256(body)) msgSequence = struct.unpack('<I', msg[-1])[-1] assert_equal(msgSequence, blockcount+1) assert_equal(hashRPC, hashZMQ) # txid from sendtoaddress must be equal to the hash received over zmq assert_equal(hashRPC, hashedZMQ)
return all_inputs def sign_stake_tx(self, block, stake_in_value, fZPoS=False): ''' signs a coinstake transaction :param block: (CBlock) block with stake to sign stake_in_value: (int) staked amount fZPoS: (bool) zerocoin stake :return: stake_tx_signed: (CTransaction) signed tx ''' self.block_sig_key = CECKey() else: # Create a new private key and get the corresponding public key self.block_sig_key.set_secretbytes(hash256(pack('<I', 0xffff))) pubkey = self.block_sig_key.get_pubkey() # Create the raw stake TX (unsigned) scriptPubKey = CScript([pubkey, OP_CHECKSIG]) outNValue = int(stake_in_value + 2*COIN) stake_tx_unsigned = CTransaction() stake_tx_unsigned.nTime = block.nTime stake_tx_unsigned.vin.append(CTxIn(block.prevoutStake)) stake_tx_unsigned.vin[0].nSequence = 0xffffffff stake_tx_unsigned.vout.append(CTxOut()) stake_tx_unsigned.vout.append(CTxOut(outNValue, scriptPubKey)) # Sign the stake TX stake_tx_signed_raw_hex = self.node.signrawtransaction(bytes_to_hex_str(stake_tx_unsigned.serialize()))['hex'] # Deserialize the signed raw tx into a CTransaction object and return it stake_tx_signed = CTransaction()
def run_test(self): """Main test logic""" self.log.info("Starting test!") [n0, n1, n2] = self.nodes # n2 is the erasing node self.log.info("Generate a few blocks upfront to make sure pruning kicks in.") # On pruning, we must have a chain longer than PruneAfterHeight and bigger than 550 MiB. mine_large_blocks(n0, nblocks=200) self.nodes[0].generate(nblocks=200) self.log.info("Build a \"bad\" transaction.") bad_data = 'n42MaFLwantedToTestThisKYP112MM9jE' tx_bad = n1.createrawtransaction([], {bad_data: 0.001}) (tx_bad, txid_bad) = fund_sign_send(n1, tx_bad) # also adds inputs and change output tx_bad_vouts = n1.decoderawtransaction(tx_bad)['vout'] self.log.info("Add tx to a block, mine a few big blocks on top.") self.sync_all() block_hash_bad = n0.generate(nblocks=1)[0] # significantly lower nblocks might cause pruning not to work (needs changes to bitcoind pruning logic) mine_large_blocks(n0, nblocks=300) self.nodes[0].generate(nblocks=300) self.sync_all() erase_target = {block_hash_bad: {txid_bad: list(range(len(tx_bad_vouts)))}} self.log.info("Assert that node 2 serves the tx via RPC.") assert_equal(bytes_to_hex_str(hash256(hex_str_to_bytes(n2.getrawtransaction(txid_bad)))), txid_bad) self.log.info("Assert that node 2 serves the block with the tx via P2P.") n2.add_p2p_connection(P2PInterface()) n2.p2p.send_message(msg_getdata(inv=[CInv(2, int(block_hash_bad, 16))])) n2.p2p.wait_for_block(int(block_hash_bad, 16), timeout=1) self.log.info("Stopping node 2.") self.stop_node(2) self.log.info("Assert that UTXOs not erased according to tool.") assert_equal(tool.check(erase_target, n2.datadir, 'regtest'), False) def react_to_ui_request(request): assert("enable pruning" in request) self.log.info("Configuring node 2 to enable pruning.") append_config(n2.datadir, ["prune=1"]) assert("start your node" in request) self.log.info("Starting node 2.") self.start_node(2) connect_nodes_bi(self.nodes, 0, 2) self.log.info("Erasing using tool.") tool.interactive_erase(erase_target, n2.datadir, 'regtest', self.log.info, react_to_ui_request) self.log.info("Assert that the tx's block can't be obtained from node 2 via P2P anymore.") n2.add_p2p_connection(P2PInterface()) n2.p2p.send_message(msg_getdata(inv=[CInv(2, int(block_hash_bad, 16))])) assert_raises(AssertionError, n2.p2p.wait_for_block, int(block_hash_bad, 16), timeout=1) self.log.info("Assert that tx is different now when obtained from node 2 via RPC.") assert_raises_rpc_error(-5, None, n2.getrawtransaction, txid_bad) self.log.info("Assert that node 2 accepts new blocks.") n0.generate(nblocks=1) sync_blocks(self.nodes, timeout=1) self.log.info("Spend one output of the bad tx, include that in block.") tx_bad_vout = [x for x in n1.listunspent() if x['txid'] == txid_bad][0] tx_ok = n1.createrawtransaction([tx_bad_vout], {n0.getnewaddress(): 0.5}) (tx_ok, txid_ok) = fund_sign_send(n1, tx_ok) sync_mempools([n0, n1]) n0.generate(nblocks=1) self.log.info("Assert that node 2 accepts the resulting transaction and block.") sync_blocks(self.nodes, timeout=1) assert_equal(bytes_to_hex_str(hash256(hex_str_to_bytes(n2.getrawtransaction(txid_ok)))), txid_ok) self.log.info("Wait for all nodes to sync again, just in case. Should complete immediately.") self.sync_all() self.log.info("Stopping node 2 (again).") self.stop_node(2) self.log.info("Assert that UTXOs are erased according to tool.") assert_equal(tool.check(erase_target, n2.datadir, 'regtest'), True)
def _zmq_test(self): num_blocks = 5 self.log.info( "Generate {0} blocks (and {0} coinbase txes)".format(num_blocks)) genhashes = self.nodes[0].generate(num_blocks) self.sync_all() for x in range(num_blocks): # Should receive the coinbase txid. txid = self.hashtx.receive() # Should receive the coinbase raw transaction. hex = self.rawtx.receive() tx = CTransaction() tx.deserialize(BytesIO(hex)) tx.calc_sha256() assert_equal(tx.hash, txid.hex()) # Should receive the generated block hash. hash = self.hashblock.receive().hex() assert_equal(genhashes[x], hash) # The block should only have the coinbase txid. assert_equal([txid.hex()], self.nodes[1].getblock(hash)["tx"]) # Should receive the generated raw block. block = self.rawblock.receive() assert_equal(genhashes[x], hash256(block[:80]).hex()) self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress( self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, txid.hex()) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, hash256(hex).hex()) self.log.info("Test the getzmqnotifications RPC") assert_equal(self.nodes[0].getzmqnotifications(), [ { "type": "pubhashblock", "address": ADDRESS }, { "type": "pubhashtx", "address": ADDRESS }, { "type": "pubrawblock", "address": ADDRESS }, { "type": "pubrawtx", "address": ADDRESS }, ]) assert_equal(self.nodes[1].getzmqnotifications(), [])
<<<<<<< HEAD self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() ======= if self.is_wallet_compiled(): self.log.info("Wait for tx from second node") payment_txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, txid.hex()) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, hash256(hex).hex()) >>>>>>> 3001cc61cf11e016c403ce83c9cbcfd3efcbcfd9 # Should receive the broadcasted txid. txid = self.hashtx.receive() assert_equal(payment_txid, bytes_to_hex_str(txid)) # Should receive the broadcasted raw transaction. hex = self.rawtx.receive() assert_equal(payment_txid, bytes_to_hex_str(hash256(hex))) if __name__ == '__main__': ZMQTest().main()