def test_add_good_block(monkeypatch): """ test add a good block """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) assert hblockchain.add_block(block_0) == True monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) assert hblockchain.add_block(block_1) == True hblockchain.blockchain.clear()
def test_merkle_root_empty_tx(monkeypatch): """ test the merkle root for an empty transaction list """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_0, "tx", []) monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setitem(block_1, "tx", []) assert hblockchain.add_block(block_1) == False
def test_add_good_block(monkeypatch): """ test add a good block """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) assert hblockchain.add_block(block_0) == True monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) assert hblockchain.add_block(block_1) == True hblockchain.blockchain.clear()
def test_block_type(monkeypatch): """ tests the type of a block """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) assert hblockchain.validate_block(block_0) == True
def make_miner_keys(): """ makes a public-private key pair that the miner will use to receive the mining reward and the transaction fee for each transaction. This function writes the keys to a file and returns hash: RIPEMD160(SHA256(public key)) """ try: keys = rcrypt.make_ecc_keys() privkey = keys[0] pubkey = keys[1] pkhash = rcrypt.make_SHA256_hash(pubkey) mdhash = rcrypt.make_RIPEMD160_hash(pkhash) # write the keys to file with the private key as a hexadecimal string f = open('coinbase_keys.txt', 'a') f.write(privkey) f.write('\n') # newline f.write(pubkey) f.write('\n') f.close() except Exception as err: logging.debug('make_miner_keys: exception: ' + str(err)) return mdhash
def test_missing_timestamp(monkeypatch): """ test for a missing timestamp """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setitem(block_1, "timestamp", "") assert hblockchain.add_block(block_1) == False
def test_make_coinbase_transaction(): """ tests making a coinbase transaction """ ctx = hmining.make_coinbase_transaction(10, "synthetic pubkey") assert len(ctx["vin"]) == 0 assert len(ctx["vout"]) == 1 hash = rcrypt.make_RIPEMD160_hash(rcrypt.make_SHA256_hash("synthetic pubkey")) assert ctx["vout"][0]["ScriptPubKey"][1] == hash
def test_negative_difficulty_bit(monkeypatch): """ test for negative difficulty bits """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setitem(block_1, "difficulty_bits", -5) assert hblockchain.add_block(block_1) == False
def test_difficulty_type(monkeypatch): """ test difficulty bits has the wrong type" """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_0, "difficulty_bits", "20") assert hblockchain.add_block(block_0) == False
def test_negative_timestamp(monkeypatch): """ test for a negative timestamp """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_0, "timestamp", -2) assert hblockchain.add_block(block_0) == False
def test_block_nonce_type(monkeypatch): """ test nonce has the wrong type" """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_0, "nonce", "0") assert hblockchain.add_block(block_0) == False
def test_bad_nonce(monkeypatch): """ test for a negative nonce """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setitem(block_1, "nonce", -1) assert hblockchain.add_block(block_1) == False
def test_no_consecutive_duplicate_blocks(monkeypatch): """ test cannot add the same block twice consecutively to the blockchain """ hblockchain.blockchain.clear() monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) assert hblockchain.add_block(block_0) == True monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setitem(block_1, "prevblockhash", hblockchain.blockheader_hash(block_0)) assert hblockchain.add_block(block_1) == True monkeypatch.setitem(block_1, "height", 2) assert hblockchain.add_block(block_1) == False hblockchain.blockchain.clear()
def test_version_bad(monkeypatch): """ test for an unknown version number """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setitem(block_1, "version", -1) assert hblockchain.add_block(block_1) == False
def test_bad_timestamp_type(monkeypatch): """ test for a bad timestamp type """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setitem(block_1, "timestamp", "12345") assert hblockchain.add_block(block_1) == False
def test_missing_difficulty_bit(monkeypatch): """ test for missing difficulty bits """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('data')) monkeypatch.setitem(block_1, "difficulty_bits", '') assert hblockchain.add_block(block_1) == False
def test_missing_nonce(monkeypatch): """ test for a missing nonce """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_0, "nonce", "") assert hblockchain.add_block(block_0) == False
def test_block_height_type(monkeypatch): """ test the type of the block height parameter """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_0, "height", "0") hblockchain.blockchain.clear() assert hblockchain.add_block(block_0) == False
def test_missing_difficulty_bit(monkeypatch): """ test for missing difficulty bits """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) monkeypatch.setitem(block_1, "difficulty_bits", '') assert hblockchain.add_block(block_1) == False
def test_negative_timestamp(monkeypatch): """ test for a negative timestamp """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) monkeypatch.setitem(block_0, "timestamp", -2) assert hblockchain.add_block(block_0) == False
def test_bad_nonce(monkeypatch): """ test for a negative nonce """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) monkeypatch.setitem(block_1, "nonce", -1) assert hblockchain.add_block(block_1) == False
def test_missing_nonce(monkeypatch): """ test for a missing nonce """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) monkeypatch.setitem(block_0, "nonce", "") assert hblockchain.add_block(block_0) == False
def test_read_genesis_block(monkeypatch): """ test reading the genesis block from the blockchain """ hblockchain.blockchain.clear() monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) hblockchain.add_block(block_0) assert hblockchain.read_block(0) == block_0 hblockchain.blockchain.clear()
def test_bad_timestamp_type(monkeypatch): """ test for a bad timestamp type """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) monkeypatch.setitem(block_1, "timestamp", "12345") assert hblockchain.add_block(block_1) == False
def test_difficulty_type(monkeypatch): """ test difficulty bits has the wrong type" """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) monkeypatch.setitem(block_0, "difficulty_bits", "20") assert hblockchain.add_block(block_0) == False
def test_version_bad(monkeypatch): """ test for an unknown version number """ monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) monkeypatch.setattr(blk_index, "put_index", lambda x, y: None) monkeypatch.setattr(tx, "validate_transaction", lambda x, y: True) monkeypatch.setitem(block_1, "version", -1) assert hblockchain.add_block(block_1) == False
def unlock_transaction_fragment(vinel: "dictionary", fragment: "dictionary") -> "boolean": """ unlocks a previous transaction fragment using the p2pkhash script. Executes the script and returns False if the transaction is not unlocked Receives: the consuming vin and the previous transaction fragment consumed by the vin element. """ try: execution_stack = [] result_stack = [] # make the execution stack for a p2pkhash script # since we only have one type of script in Helium # we can use hard-coded values execution_stack.append('SIG') execution_stack.append('PUBKEY') execution_stack.append('<DUP>') execution_stack.append('<HASH_160>') execution_stack.append('HASH-160') execution_stack.append('<EQ-VERIFY>') execution_stack.append('<CHECK_SIG>') # Run the p2pkhash execution stack result_stack.insert(0, vinel['ScriptSig'][0]) result_stack.insert(0, vinel['ScriptSig'][1]) result_stack.insert(0, vinel['ScriptSig'][1]) hash_160 = rcrypt.make_SHA256_hash(vinel['ScriptSig'][1]) hash_160 = rcrypt.make_RIPEMD160_hash(hash_160) result_stack.insert(0, hash_160) result_stack.insert(0, fragment["pkhash"]) # do the EQ_VERIFY operation tmp1 = result_stack.pop(0) tmp2 = result_stack.pop(0) # test for RIPEMD-160 hash match if tmp1 != tmp2: raise (ValueError("public key match failure")) # test for a signature match ret = rcrypt.verify_signature(vinel['ScriptSig'][1], vinel['ScriptSig'][1], vinel['ScriptSig'][0]) if ret == False: raise (ValueError("signature match failure")) except Exception as err: logging.debug('unlock_transaction_fragment: exception: ' + str(err)) return False return True
def test_unlock_bad_signature(monkeypatch): """ test unlocking a transaction with a bad signature """ global prev_tx_keys prev_tx_keys.clear() txn1 = make_synthetic_previous_transaction(4) txn2 = make_synthetic_transaction(2) # make a transaction fragment where the first vin element # of txn2 consumes the value of the first vout element of txn1 # synthetic consuming vin element in tx2 vin = {} vin['txid'] = txn1["transactionid"] vin['vout_index'] = 0 vin['ScriptSig'] = {} # use wrong private key to sign key_pair = rcrypt.make_ecc_keys() signature = rcrypt.sign_message(key_pair[0], prev_tx_keys[1][1]) pubkey = prev_tx_keys[1][1] sig = [] sig.append(signature) sig.append(pubkey + "corrupted") vin['ScriptSig'] = sig # public key hash in txn2 ripemd_hash = rcrypt.make_RIPEMD160_hash(rcrypt.make_SHA256_hash(prev_tx_keys[1][1])) fragment = { "value": 210, "pkhash": ripemd_hash, "spent": False, "tx_chain": txn2["transactionid"] + "_" + "0", "checksum": rcrypt.make_SHA256_hash(txn1["transactionid"]) } assert tx.unlock_transaction_fragment(vin, fragment) == False
def test_genesis_block_prev_hash(monkeypatch): """ test that the previous block hash for the genesis block is empty """ hblockchain.blockchain.clear() monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_0, "height", 0) monkeypatch.setitem(block_0, "prevblockhash", rcrypt.make_uuid()) assert len(hblockchain.blockchain) == 0 assert hblockchain.add_block(block_0) == False
def test_invalid_previous_hash(monkeypatch): """ test block's prevblockhash is invalid """ hblockchain.blockchain.clear() monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg0')) monkeypatch.setitem(block_2, "prevblockhash", \ "188a1fd32a1f83af966b31ca781d71c40f756a3dc2a7ac44ce89734d2186f632") hblockchain.blockchain.clear() assert hblockchain.add_block(block_0) == True monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg1')) assert hblockchain.add_block(block_1) == True monkeypatch.setattr(hblockchain, "merkle_root", lambda x, y: rcrypt.make_SHA256_hash('msg2')) assert hblockchain.add_block(block_2) == False hblockchain.blockchain.clear()