def test_staking_transaction(): transaction = Transaction( chain=1, nonce=4_294_967_295, fee=57000, value=5_000_000, to_address=Config.STAKING_ADDRESS, unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) assert transaction.validate() is False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_INVALID_STAKING): transaction.validate_fields(raise_exception=True) transaction = Transaction( chain=1, nonce=4_294_967_295, fee=57000, value=5_000_000, to_address=Config.STAKING_ADDRESS, ) transaction = transaction.sign(unhexlify(WALLET_1["private_key"])) assert transaction.validate() is True
def test_block_save(): coinbase_transaction_1 = Transaction( chain=1, nonce=1, fee=0, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block1 = Block( version=1, height=0, miner=WALLET_1["address"], prev_block_hash="0" * 64, timestamp=1_623_168_442, bits=b"\x1d\x0f\xff\xff", nonce=12308683, txns=[coinbase_transaction_1], ) print(block1.json()) coinbase_transaction_2 = Transaction( chain=1, nonce=2, fee=0, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block2 = Block( version=1, height=1, miner=WALLET_1["address"], prev_block_hash=block1.id, timestamp=1_623_168_442, bits=b"\x1d\x0f\xff\xff", nonce=12308683, txns=[coinbase_transaction_2], ) print(block2.json()) chain = Chain() assert chain.tip == 0 block1.save() assert chain.tip == 0 block2.save() assert chain.tip == 1 assert False
def test_validate(): coinbase_transaction_1 = Transaction( chain=1, nonce=1, fee=0, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block1 = Block( version=1, height=0, prev_block_hash="0" * 64, timestamp=1_623_168_442, bits=Config.STARTING_DIFFICULTY, nonce=0, txns=[coinbase_transaction_1], ) assert block1.validate() is False proof_of_work(block=block1, starting_at=4334955) assert block1.nonce == 4334956 assert block1.validate() is True transactions = add_test_transactions() coinbase_transaction_2 = Transaction( chain=1, nonce=2, fee=0, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block2 = Block( version=1, height=1, prev_block_hash=block1.id, timestamp=1_623_208_442, bits=Config.STARTING_DIFFICULTY, nonce=0, txns=[coinbase_transaction_2, *transactions], ) proof_of_work(block=block2, starting_at=1162892) assert block2.nonce == 1162893
def test_block_serialize__with_one_transaction(blockchain): coinbase_transacion = Transaction( chain=1, nonce=8763, fee=100, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block1 = Block( version=1, height=0, miner=WALLET_1["address"], prev_block_hash="0" * 64, timestamp=1_623_168_442, bits=b"\x1f\x00\xff\xff", nonce=0, txns=[coinbase_transacion], ) block2 = Block().deserialize(block1.serialize()) assert block1.id == block2.id assert block1.json() == block2.json()
def test_transaction_validate(transaction1, transaction2): # type: ignore assert transaction1.validate() is True assert transaction2.validate() is True tx = Transaction( version=1, txins=[ TxIn( to_spend=OutPoint(Config.COINBASE_TX_ID, Config.COINBASE_TX_INDEX), unlock_sig="0", sequence=0, ) ], txouts=[ TxOut( value=3_000_000_000, to_address=build_p2pkh("1DNFUMhT4cm4qbZUrbAApN3yKJNUpRjrTS"), ), TxOut( value=2_500_000_000, to_address=build_p2pkh("1DNFUMhT4cm4qbZUrbAApN3yKJNUpRjrTS"), ), ], locktime=0, ) assert tx.validate() is False
def test_to_json(): transacion = Transaction( chain=1, nonce=8763, fee=100, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig= b"~\xf8su\xeb\xeb\xc9\xd4\xcd\r\x17\x08\xe5#Oo\x05D\x85\x94\x04\x88\x8f\xf9\xcb\xfc\x9amzdG\xb4.\xdc\xac\x14\xcc\x95\x8cI\x9e\xfer\xe4\x051(\x08\x8e5\x0f(]s\x89g\xe7|\xd9\xee\xf8'B\x17\xb8\xb2\x14\xfc\x03\x87;b\xab\xcc^\xfc\xf5\xee\x84\\'h\xe0\x97\xe2\xaeI+\x9al\xe3;:~;]3l,\xab[^v\xef&E\x9d\xbaS\x1c\xe2\x04\xcaC\x15W\x9fR0\xc6}\xe4\xe6\x80\x99\xdf!\x15", ) assert transacion.json() == { "id": "d24b6dae6bc576b367ac29a981727d221b9e1211280dc4bb24a4c4d2808c82f0", "chain": 1, "nonce": 8763, "fee": 100, "value": 50000, "to_address": "1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", "unlock_sig": "7ef87375ebebc9d4cd0d1708e5234f6f0544859404888ff9cbfc9a6d7a6447b42edcac14cc958c499efe72e4053128088e350f285d738967e77cd9eef8274217b8b214fc03873b62abcc5efcf5ee845c2768e097e2ae492b9a6ce33b3a7e3b5d336c2cab5b5e76ef26459dba531ce204ca4315579f5230c67de4e68099df2115", }
def test_nonce(mocker): """ Test to validate the field 'nonce' from a transaction """ transaction = Transaction( chain=0, nonce=14_294_967_296, fee=57000, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_NONCE): transaction.validate(raise_exception=True) transaction.nonce = 1_260_300 assert transaction.validate() == True assert transaction.validate(raise_exception=True) == True transaction.nonce = -1 assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_NONCE): transaction.validate(raise_exception=True)
def test_chain(mocker): """ Test to validate the field 'chain' from a transaction. """ transaction = Transaction( chain=-1, nonce=4_294_967_295, fee=57000, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_CHAIN): transaction.validate(raise_exception=True) transaction.chain = 15 assert transaction.validate() == True assert transaction.validate(raise_exception=True) == True transaction.chain = 257 assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_CHAIN): transaction.validate(raise_exception=True)
def test_unlock_sig(mocker): """ Test to validate the field 'unlock_sig' from a transaction """ transaction = Transaction( chain=1, nonce=10, fee=50, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) assert transaction.validate_fields() == True assert transaction.validate_fields(raise_exception=True) == True transaction.unlock_sig = binascii.unhexlify("0" * 258) assert transaction.validate_fields() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_SIGNATURE): transaction.validate_fields(raise_exception=True) transaction.unlock_sig = binascii.unhexlify("1" * 256) assert transaction.validate_fields() == True assert transaction.validate_fields(raise_exception=True) == True
def test_block_serialize__with_multiple_transaction(): coinbase_transaction_1 = Transaction( chain=1, nonce=1, fee=0, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block1 = Block( version=1, height=0, miner=WALLET_1["address"], prev_block_hash="0" * 64, timestamp=1_623_168_442, bits=b"\x1f\x00\xff\xff", nonce=0, txns=[coinbase_transaction_1], ) transactions = add_test_transactions() coinbase_transaction_2 = Transaction( chain=1, nonce=2, fee=0, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block2 = Block( version=1, height=1, miner=WALLET_1["address"], prev_block_hash=block1.id, timestamp=1_623_208_442, bits=b"\x1f\x00\xff\xff", nonce=0, txns=[coinbase_transaction_2, *transactions], ) block3 = Block().deserialize(block2.serialize()) assert block2.id == block3.id assert block2.json() == block3.json()
def test_serializer_with_coinbase_signatures(): transaction_original = Transaction( chain=1, nonce=4_294_967_295, fee=57000, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) expected_serialization_hex = "01ffffffffa8de0000404b4c00000000003148374e7455454e7245627753566d3532664865507a426e75345733624371696d500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" expected_serialization_bytes = b"\x01\xff\xff\xff\xff\xa8\xde\x00\x00@KL\x00\x00\x00\x00\x001H7NtUENrEbwSVm52fHePzBnu4W3bCqimP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" assert transaction_original.serialize().hex() == expected_serialization_hex assert transaction_original.serialize() == expected_serialization_bytes transaction = Transaction() transaction.deserialize(expected_serialization_bytes) assert transaction_original.json() == transaction.json()
def test_transaction_serializer_to_sign(): transaction_original = Transaction( chain=1, nonce=4_294_967_295, fee=57000, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", ) expected_serialization_hex = "01ffffffffa8de0000404b4c00000000003148374e7455454e7245627753566d3532664865507a426e75345733624371696d50" expected_serialization_bytes = b"\x01\xff\xff\xff\xff\xa8\xde\x00\x00@KL\x00\x00\x00\x00\x001H7NtUENrEbwSVm52fHePzBnu4W3bCqimP" assert (transaction_original.serialize( to_sign=True).hex() == expected_serialization_hex) assert (transaction_original.serialize( to_sign=True) == expected_serialization_bytes) transaction = Transaction() transaction.deserialize(expected_serialization_bytes) assert transaction_original.json() == transaction.json()
def select_transactions(self) -> "Block": redis_client = redis.Redis(host=Config.REDIS_HOST, port=Config.REDIS_PORT, db=Config.REDIS_DB) keys = redis_client.keys() transactions = [] for key in sorted(keys): serialized_tx = redis_client.get(key) txn = Transaction() txn.deserialize(serialized_tx.hex()) transactions.append(txn) self.txns = transactions return self
def test_validate_signatures(mocker): """ Test to check that the signatures are valid. """ transaction_original = Transaction( chain=1, nonce=4_294_967_295, fee=57000, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", ) transaction = transaction_original.sign(PRIVATE_KEY_1) assert transaction.validate() == True # Incorrect Public Key / Signature with mocker.patch( "luracoin.transactions.deserialize_unlocking_script", return_value= { "signature": "6cfa3bd7427ec06e8c0e93911db0932fa18f763f617f4115929501affd0f95aacc71c66d0c7c535f3843d537cb5c424bb0ee59e5baf6df8966c6b58faa2abfc2", "public_key": "533b17c5cf044c799a67ad974250aeb72cb529ae59f4b8804adc6eb602dd5ee35c6f8a1910dd7924f89a624456f3c0f4e2c6d4117ee0fa7419af6c7ca120d596", "address": "1C5fcCCJydpyQ7KqHBuGHJbwrwURHd62Lj", }, ): assert transaction.validate() == False # Invalid Public Key with mocker.patch( "luracoin.transactions.deserialize_unlocking_script", return_value= { "signature": "6cfa3bd7427ec06e8c0e93911db0932fa18f763f617f4115929501affd0f95aacc71c66d0c7c535f3843d537cb5c424bb0ee59e5baf6df8966c6b58faa2abfc2", "public_key": "0000000000000455d0fd9a38f1befcf1c7116feedd7407f42fcf4ad321e4710014740c3c370109a585debfb082d0889b99fa74708c3f41f0b3d39498cb65b3ee", "address": "1C5fcCCJydpyQ7KqHBuGHJbwrwURHd62Lj", }, ): assert transaction.validate() == False transaction.to_transaction_pool()
def test_modify_transaction_after_signing(mocker): """ Test to check that you can't modify a transaction after signing it. """ transaction_original = Transaction( chain=0, nonce=4_294_967_295, fee=57000, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", ) transaction = transaction_original.sign(PRIVATE_KEY_1) transaction.value = 10_000_000 assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_INVALID_SIGNATURE): transaction.validate(raise_exception=True)
def deserialize(self, block_serialized: bytes) -> "Block": self.version = int.from_bytes(block_serialized[0:4], byteorder="little") self.prev_block_hash = block_serialized[36:68].hex() self.height = int.from_bytes(block_serialized[68:72], byteorder="little") self.miner = block_serialized[72:106].decode("utf-8") self.timestamp = int.from_bytes(block_serialized[106:110], byteorder="big") self.bits = block_serialized[110:114] self.nonce = int.from_bytes(block_serialized[114:118], byteorder="little") self.txns = [] block_transations = block_serialized[118:] for i in range(0, len(block_transations), 179): txn = Transaction() txn.deserialize(block_transations[i:i + 179]) self.txns.append(txn) return self
def test_to_address(mocker): """ Test to validate the field 'to_address' from a transaction """ transaction = Transaction( chain=1, nonce=10, fee=50, value=5_000_000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) assert transaction.validate() == True assert transaction.validate(raise_exception=True) == True transaction.to_address = "1H7NtUENrEbwSVm52fHePzBnu4W3bCqimPX" assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_TO_ADDRESS): transaction.validate(raise_exception=True)
def init_blockchain(): """ Initialize blockchain with genesis block """ coinbase_transacion = Transaction( chain=1, nonce=8763, fee=100, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=None, ) block1 = Block( version=1, height=0, prev_block_hash="0" * 64, timestamp=1_623_168_442, bits=b"\1f\x00\xff\xff", nonce=0, txns=[coinbase_transacion], )
def test_value(mocker): """ Test to validate the field 'value' from a transaction """ transaction = Transaction( chain=0, nonce=0, fee=0, value=18_446_744_073_709_551_616, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_VALUE): transaction.validate(raise_exception=True) transaction.value = 18_446_744_073_709_551_615 assert transaction.validate() == True assert transaction.validate(raise_exception=True) == True transaction.value = 9_551_615 assert transaction.validate() == True assert transaction.validate(raise_exception=True) == True transaction.value = 0 assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_VALUE): transaction.validate(raise_exception=True) transaction.value = -1 assert transaction.validate() == False with pytest.raises(TransactionNotValid, match=errors.TRANSACTION_FIELD_VALUE): transaction.validate(raise_exception=True)
import pytest from luracoin.blocks import Block from luracoin.config import Config from luracoin.transactions import OutPoint, Transaction, TxIn, TxOut from luracoin.wallet import build_p2pkh coinbase1 = Transaction( version=1, txins=[ TxIn( to_spend=OutPoint(Config.COINBASE_TX_ID, Config.COINBASE_TX_INDEX), unlock_sig="0", sequence=0, ) ], txouts=[ TxOut( value=3_000_000_000, to_address=build_p2pkh("1QHxaBNsCtYXj8M6CUi7fUeNY2FE2m7t8e"), ), TxOut( value=1_500_000_000, to_address=build_p2pkh("16iFwTZFLhDVY3sK1K3oBRLNkJCjHBJv1E"), ), TxOut( value=500_000_000, to_address=build_p2pkh("1ByCQKMDiRM1cp14vrpz4HCBz7A6LJ5XJ8"), ), ], locktime=0,
def add_test_transactions(): transaction1 = Transaction( chain=1, nonce=1, fee=57000, value=5_000_000, to_address=WALLET_2["address"], ) transaction1 = transaction1.sign(unhexlify(WALLET_1["private_key"])) assert transaction1.validate() == True transaction1.to_transaction_pool() transaction2 = Transaction( chain=1, nonce=1, fee=157_000, value=15_000_000, to_address=WALLET_3["address"], ) transaction2 = transaction2.sign(unhexlify(WALLET_2["private_key"])) assert transaction2.validate() == True transaction2.to_transaction_pool() transaction3 = Transaction( chain=1, nonce=2, fee=5700, value=500_000, to_address=WALLET_1["address"], ) transaction3 = transaction3.sign(unhexlify(WALLET_2["private_key"])) assert transaction3.validate() == True transaction3.to_transaction_pool() transaction4 = Transaction(chain=1, nonce=2, fee=50, value=100, to_address=WALLET_1["address"]) transaction4 = transaction4.sign(unhexlify(WALLET_2["private_key"])) assert transaction4.validate() == True transaction4.to_transaction_pool() transaction5 = Transaction(chain=1, nonce=2, fee=150, value=600, to_address=WALLET_2["address"]) transaction5 = transaction5.sign(unhexlify(WALLET_3["private_key"])) assert transaction5.validate() == True transaction5.to_transaction_pool() return [ transaction1, transaction2, transaction3, transaction4, transaction5, ]
def deserialize(self, block_serialized: str) -> None: magic = block_serialized[0:8] block_version = block_serialized[8:16] prev_hash = block_serialized[16:80] # block_hash = block_serialized[80:144] bits = block_serialized[144:152] timestamp = block_serialized[152:160] nonce = block_serialized[160:172] if magic != Config.MAGIC_BYTES: raise BlockNotValidError self.version = little_endian_to_int(block_version) self.prev_block_hash = prev_hash self.timestamp = little_endian_to_int(timestamp) self.bits = little_endian_to_int(bits) self.nonce = little_endian_to_int(nonce) block_body = block_serialized[172:] num_bytes = var_int_to_bytes(block_body[0:2]) if num_bytes == 1: num_txs_serialized = block_body[0:2] num_txs_total_chars_len = 2 else: num_txs_serialized = block_body[2:num_bytes * 2] num_txs_total_chars_len = 2 + num_bytes * 2 num_txs = little_endian_to_int(num_txs_serialized) block_body = block_serialized[172 + num_txs_total_chars_len:] for _ in range(num_txs): # - Version (2 bytes) # - Num Inputs (VARINT) # - TX ID (32 bytes) # - VOUT (4 bytes) # - unlock_sig_size (VARINT) # - unlock_sig (VARINT) # - sequence (4 bytes) # - Num Outputs # - Value (8 bytes) # - Script Size (VARINT) # - Script (VARINT) # Version version = little_endian_to_int(block_body[:4]) block_body = block_body[4:] # Num Inputs bytes_for_num_inputs = var_int_to_bytes(block_body[0:2]) if bytes_for_num_inputs == 1: num_inputs_serialized = block_body[0:2] num_inputs_total_chars_len = 2 else: num_inputs_serialized = block_body[2:bytes_for_num_inputs * 2] num_inputs_total_chars_len = 2 + bytes_for_num_inputs * 2 num_inputs = little_endian_to_int(num_inputs_serialized) block_body = block_body[num_inputs_total_chars_len:] txin_list = [] for _ in range(num_inputs): tx_id = block_body[0:64] vout = little_endian_to_int(block_body[64:72]) block_body = block_body[72:] bytes_for_unlock_sig_size = var_int_to_bytes(block_body[0:2]) if bytes_for_unlock_sig_size == 1: unlock_sig_size_serialized = block_body[0:2] unlock_sig_size_total_chars_len = 2 else: unlock_sig_size_serialized = block_body[ 2:bytes_for_unlock_sig_size * 2] unlock_sig_size_total_chars_len = ( 2 + bytes_for_unlock_sig_size * 2) unlock_sig_size = little_endian_to_int( unlock_sig_size_serialized) block_body = block_body[unlock_sig_size_total_chars_len:] unlock_sig = block_body[0:unlock_sig_size] block_body = block_body[unlock_sig_size:] sequence = little_endian_to_int(block_body[0:8]) block_body = block_body[8:] txin_list.append( TxIn( to_spend=OutPoint(tx_id, vout), unlock_sig=unlock_sig, sequence=sequence, )) # Num outputs bytes_for_num_outputs = var_int_to_bytes(block_body[0:2]) if bytes_for_num_outputs == 1: num_outputs_serialized = block_body[0:2] num_outputs_total_chars_len = 2 else: num_outputs_serialized = block_body[2:bytes_for_num_outputs * 2] num_outputs_total_chars_len = 2 + bytes_for_num_outputs * 2 num_outputs = little_endian_to_int(num_outputs_serialized) block_body = block_body[num_outputs_total_chars_len:] txout_list = [] for _ in range(num_outputs): txout = TxOut() value = little_endian_to_int(block_body[0:16]) txout.value = value block_body = block_body[16:] bytes_for_script_size = var_int_to_bytes(block_body[0:2]) if bytes_for_script_size == 1: script_size_serialized = block_body[0:2] script_size_total_chars_len = 2 else: script_size_serialized = block_body[ 2:bytes_for_script_size * 2] script_size_total_chars_len = 2 + bytes_for_script_size * 2 script_size = little_endian_to_int(script_size_serialized) block_body = block_body[script_size_total_chars_len:] script = block_body[0:script_size] txout.to_address = script block_body = block_body[script_size:] txout_list.append(TxOut(value=value, to_address=script)) self.txns.append( Transaction(version=version, txins=txin_list, txouts=txout_list))
import binascii import json from tests.helpers import add_test_transactions from luracoin.helpers import bits_to_target from luracoin.blocks import Block from luracoin.transactions import Transaction from tests.helpers import add_test_transactions from luracoin.config import Config from luracoin.pow import proof_of_work coinbase_transaction_1 = Transaction( chain=1, nonce=1, fee=0, value=50000, to_address="1H7NtUENrEbwSVm52fHePzBnu4W3bCqimP", unlock_sig=Config.COINBASE_UNLOCK_SIGNATURE, ) block1 = Block( version=1, height=0, prev_block_hash="0" * 64, timestamp=1_623_168_442, bits=b"\x1d\x0f\xff\xff", nonce=0, txns=[coinbase_transaction_1], ) # Nonce: 12308683
def test_full_blockchain(): START_TIMESTAMP = 1639159886 chain = Chain() assert chain.tip == 0 block1 = Block( version=1, height=0, prev_block_hash="0" * 64, miner=WALLET_1["address"], timestamp=START_TIMESTAMP, bits=Config.STARTING_DIFFICULTY, nonce=156369, txns=[], ) print("\nBlock 1 \n" + json.dumps(block1.json(), indent=4)) block1.save() # Check chain Height is updated assert chain.tip == 0 # Check block file number is updated assert chain.get_block_file_number(0) == 0 # Check that the block file contains one block assert len(Block.get_blocks_from_file(0)) == 1 # Check that the block retrieved from the files is the same assert Block.get(0).id == block1.id assert Block.get(0).serialize() == block1.serialize() # TODO: Check miner balance # TODO: Check file content # TODO: Check stacking # Transaction to stack 15 Luracoins transaction_1 = Transaction( chain=1, nonce=1, fee=0, value=Config.LURASHIS_PER_COIN * 15, to_address=Config.STAKING_ADDRESS, ) transaction_1.sign(unhexlify(WALLET_1["private_key"])) assert transaction_1.validate() == True block2 = Block( version=1, height=1, prev_block_hash=block1.id, miner=WALLET_1["address"], timestamp=START_TIMESTAMP + (3*60), # 3 minutes bits=Config.STARTING_DIFFICULTY, nonce=4358788, txns=[transaction_1], ) print("\nBlock 2 \n" + json.dumps(block2.json(), indent=4)) block2.save() # Check chain Height is updated assert chain.tip == 1 # Check block file number is updated assert chain.get_block_file_number(0) == 0 # Check that the block file contains two blocks assert len(Block.get_blocks_from_file(0)) == 2 # Check that the block retrieved from the files is the same assert Block.get(1).id == block2.id assert Block.get(1).serialize() == block2.serialize() # TODO: Check miner balance # TODO: Check file content # TODO: Check stacking assert False