Esempio n. 1
0
def test_flow_3():
    """
    This MUST NOT fail
    We add two blocks to the blockchain, the second one with a transaction which spends
    the coinbase 0 output
    """
    coinbase_0 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(10**10, Script())],
    )
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb"))],
        [TxOut(10**10, Script())],
    )
    tx = Tx([TxIn(OutPoint(coinbase_0.txid, 0), Script())],
            [TxOut(10**5, Script())])
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)
    blockchain._add_block(block_1)

    reset_blockchain()
Esempio n. 2
0
def test_flow_1():
    """
    This MUST NOT fail
    We simply add two blocks, each one with only the coinbase transaction
    """

    coinbase_0 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(10**10, Script())],
    )

    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)
    assert blockchain.last_block_pow == origin.header.pow

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb"))],
        [TxOut(10**10, Script())],
    )
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root([coinbase_1]), 0)
    block_1 = Block(block_1_header, [coinbase_1])
    blockchain._add_block(block_1)
    assert blockchain.last_block_pow == block_1.header.pow

    reset_blockchain()
Esempio n. 3
0
def test_flow_6():
    """
    This MUST fail
    The block 1 coinbase collects more fees than it should
    """
    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(2 * 10**10 - 10**5 + 1, Script())],
    )
    tx = Tx([TxIn(OutPoint(coinbase_0.txid, 0), Script())],
            [TxOut(10**5, Script())])
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)
    with pytest.raises(Exception):
        blockchain._add_block(block_1)

    reset_blockchain()
Esempio n. 4
0
def test_flow_7():
    """
    This MUST fail
    The two coinbases have the same txid
    """

    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])

    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)
    assert blockchain.last_block_pow == origin.header.pow

    coinbase_1 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root([coinbase_1]), 0)
    block_1 = Block(block_1_header, [coinbase_1])
    with pytest.raises(Exception):
        blockchain._add_block(block_1)

    reset_blockchain()
Esempio n. 5
0
def test_flow_13():

    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])

    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)
    assert blockchain.last_block_pow == origin.header.pow

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(10**10, Script())],
    )
    block_1_header = BlockHeader("ff" * 32, generate_merkle_root([coinbase_1]),
                                 0)
    block_1 = Block(block_1_header, [coinbase_1])
    with pytest.raises(Exception):
        blockchain._add_block(block_1)

    reset_blockchain()
Esempio n. 6
0
def test_flow_4():
    """
    This MUST fail
    The second block transaction tries to spend more than its input
    """
    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(10**10, Script())],
    )
    # overspends
    tx = Tx([TxIn(OutPoint(coinbase_0.txid, 0), Script())],
            [TxOut(10**10 + 1, Script())])
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)
    with pytest.raises(Exception):
        blockchain._add_block(block_1)

    reset_blockchain()
Esempio n. 7
0
def test_flow_10():
    """
    This MUST fail
    Test of block reverse
    """
    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    rev_block_0 = blockchain._add_block(origin)

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(2 * 10**10 - 10**5, Script())],
    )
    tx = Tx([TxIn(OutPoint(coinbase_0.txid, 0), Script())],
            [TxOut(10**5, Script())])
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)
    blockchain._add_block(block_1)

    with pytest.raises(Exception):
        blockchain._reverse_block(rev_block_0)

    reset_blockchain()
Esempio n. 8
0
def test_flow_9():
    """
    This MUST fail
    The transaction tries to spend an unkown utxo
    """
    coinbase_0 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(10**10, Script())],
    )
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb"))],
        [TxOut(10**10, Script())],
    )
    # tries to spend the coinbase output at index 1, which doesn't exist
    tx = Tx([TxIn(OutPoint(coinbase_0.txid, 1), Script())],
            [TxOut(10**5, Script())])
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)
    with pytest.raises(Exception):
        blockchain._add_block(block_1)

    reset_blockchain()
Esempio n. 9
0
def test_flow_11():
    """
    This MUST NOT fail
    """
    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(5 * 10**9, Script()),
         TxOut(5 * 10**9, Script())],
    )
    tx = Tx(
        [TxIn(OutPoint(coinbase_0.txid, 0), Script())],
        [TxOut(10**10 - 100, Script()),
         TxOut(50, Script())],
    )
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)
    blockchain._add_block(block_1)

    coinbase_2 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb"))],
        [TxOut(10**10, Script())],
    )
    tx_2 = Tx([TxIn(OutPoint(tx.txid, 0), Script())],
              [TxOut(10**10 - 200, Script())])
    tx_3 = Tx(
        [
            TxIn(OutPoint(coinbase_1.txid, 0), Script()),
            TxIn(OutPoint(coinbase_1.txid, 1), Script()),
            TxIn(OutPoint(tx.txid, 1), Script()),
        ],
        [TxOut(10**10 + 50, Script())],
    )
    block_2_transactions = [coinbase_2, tx_2, tx_3]
    block_2_header = BlockHeader(block_1.header.pow,
                                 generate_merkle_root(block_2_transactions), 0)
    block_2 = Block(block_2_header, block_2_transactions)
    blockchain._add_block(block_2)

    reset_blockchain()
Esempio n. 10
0
def test_flow_14():
    """
    This MUST NOT fail
    """

    blockchain = Blockchain()

    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_header = BlockHeader("00" * 32, generate_merkle_root([coinbase_0]),
                                0)
    origin = Block(origin_header, [coinbase_0])

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(5 * 10**9, Script()),
         TxOut(5 * 10**9, Script())],
    )
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root([coinbase_1]), 0)
    block_1 = Block(block_1_header, [coinbase_1])

    coinbase_2 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb"))],
        [TxOut(10**10, Script())],
    )
    block_2_header = BlockHeader(block_1.header.pow,
                                 generate_merkle_root([coinbase_2]), 0)
    block_2 = Block(block_2_header, [coinbase_2])

    # we try adding the origin again, no problem, it is skipped
    assert blockchain.add_blocks([origin, block_1, block_2])
    # invalid coinbase
    coinbase_3 = Tx(
        [
            TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa")),
            TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb")),
        ],
        [TxOut(10**10, Script())],
    )
    block_3_header = BlockHeader(block_1.header.pow,
                                 generate_merkle_root([coinbase_3]), 0)
    block_3 = Block(block_3_header, [coinbase_3])
    assert not blockchain.add_blocks([origin, block_1, block_2, block_3])

    reset_blockchain()
Esempio n. 11
0
def test_valid_serialization_1():

    tx_in = TxIn(OutPoint("ff" * 32, 0), Script())
    tx_out = TxOut(10, Script())
    tx_1 = Tx([tx_in], [tx_out])
    header = BlockHeader()
    block = Block(header, [tx_1])
    header.merkle_root = generate_merkle_root(block.transactions)
    header.previous_pow = "00" * 32
    assert Block.deserialize(block.serialize()) == block
Esempio n. 12
0
def test_mining():
    target = 16**4
    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])

    transactions = [coinbase_0]
    header = BlockHeader("00" * 32, generate_merkle_root(transactions), 0)

    nonce = calculate_nonce(header, target)
    header.nonce = nonce
    assert work_from_chain([header.pow]) > target
Esempio n. 13
0
def test_flow_8():
    """
    This MUST NOT fail
    Test of block reverse
    """
    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    rev_origin = blockchain._add_block(origin)

    old_utxo_list = blockchain.main_utxo_set.get_utxo_list()

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(2 * 10**10 - 10**5, Script())],
    )
    tx = Tx([TxIn(OutPoint(coinbase_0.txid, 0), Script())],
            [TxOut(10**5, Script())])
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)
    rev_block = blockchain._add_block(block_1)

    assert not blockchain.main_utxo_set.get_utxo_list() == old_utxo_list
    blockchain._reverse_block(rev_block)
    assert blockchain.main_utxo_set.get_utxo_list() == old_utxo_list

    with pytest.raises(Exception):
        blockchain._reverse_block(rev_block)

    blockchain._reverse_block(rev_origin)
    assert blockchain.main_utxo_set.get_utxo_list() == []

    reset_blockchain()
Esempio n. 14
0
def test_validation_2():

    tx_in = TxIn(OutPoint("00" * 32, 0), Script())
    tx_out = TxOut(10**10, Script())
    tx_1 = Tx([tx_in], [tx_out])
    header = BlockHeader()
    block = Block(header, [tx_1])
    assert not block.is_valid()

    header.merkle_root = generate_merkle_root(block.transactions)
    header.previous_pow = "00" * 32
    assert header.is_valid()
    assert block.is_valid()  # has a coinbase tx
Esempio n. 15
0
def test_flow_16():
    """
    This MUST NOT fail
    """

    blockchain = Blockchain()

    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    coinbase_0.outputs[0].locking_script = lock_p2pkh(
        pubkey_hash_from_prvkey(1))
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)
    assert blockchain.add_blocks([origin])

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script())],
        [TxOut(5 * 10**9, Script()),
         TxOut(5 * 10**9, Script())],
    )
    tx = Tx(
        [TxIn(OutPoint(coinbase_0.txid, 0), Script())],
        [TxOut(10**10 - 100, Script()),
         TxOut(50, Script())],
    )

    tx.inputs[0].unlocking_script = unlock_p2pkh(sighash_all(tx), 1)

    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)

    assert blockchain.add_blocks([block_1])

    reset_blockchain()
Esempio n. 16
0
def test_double_coinbase():
    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(10**10, Script())],
    )
    coinbase_2 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb"))],
        [TxOut(10**10, Script())],
    )
    header = BlockHeader()
    block = Block(header, [coinbase_1, coinbase_2])
    header.merkle_root = generate_merkle_root(block.transactions)
    header.previous_pow = "00" * 32
    assert not block.is_valid()
Esempio n. 17
0
def test_flow_2():
    """
    This MUST fail
    We add a block without a coinbase transaction
    """
    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)

    blockchain = Blockchain()
    blockchain._add_block(origin)

    tx = Tx([TxIn(OutPoint(coinbase_0.txid, 0), Script())],
            [TxOut(10**10, Script())])
    block_1_header = BlockHeader(origin.header.pow, generate_merkle_root([tx]),
                                 0)
    block_1 = Block(block_1_header, [tx])
    with pytest.raises(Exception):  # missing coinbase
        blockchain._add_block(block_1)

    reset_blockchain()
Esempio n. 18
0
def test_validation_3():

    tx_in = TxIn(OutPoint("ff" * 32, 256**2 - 1), Script())
    tx_out = TxOut(10, Script())
    tx_1 = Tx([tx_in], [tx_out])
    tx_in_2 = TxIn(OutPoint("ff" * 32, 256**2 - 1), Script())
    tx_out_2 = TxOut(10, Script())
    tx_2 = Tx([tx_in_2], [tx_out_2])
    header = BlockHeader()
    block = Block(header, [tx_1, tx_2])

    header.merkle_root = generate_merkle_root(block.transactions)
    header.previous_pow = "00" * 32
    assert header.is_valid()
    assert not block.is_valid()  # two coinbases
 def is_valid(self):
     if not self.header.is_valid():
         return False
     if len(self.transactions) < 1:
         return False
     merkle_root = generate_merkle_root(self.transactions)
     if not merkle_root == self.header.merkle_root:
         return False
     if (not self.transactions[0].is_coinbase()
             or not self.transactions[0].is_valid()):
         return False
     for tx in self.transactions[1:]:
         if tx.is_coinbase() or not tx.is_valid():
             return False
     return True
Esempio n. 20
0
 def is_valid(self):
     if not self.header.is_valid():
         return False
     if len(self.transactions) < 1:
         return False
     merkle_root = generate_merkle_root(self.transactions)
     if not merkle_root == self.header.merkle_root:
         return False
     if (not self.transactions[0].is_coinbase()
             or not self.transactions[0].is_valid()):
         return False
     outpoints = []
     for tx in self.transactions[1:]:
         if tx.is_coinbase() or not tx.is_valid():
             return False
         for txin in tx.inputs:
             if txin.prevout in outpoints:
                 return False
             else:
                 outpoints.append(txin.prevout)
     return True
def test_merkle_root():
    assert generate_merkle_root([])
Esempio n. 22
0
def test_flow_12():
    """
    This MUST NOT fail
    """

    blockchain = Blockchain()

    coinbase_0 = Tx([TxIn(OutPoint("00" * 32, 0), Script())],
                    [TxOut(10**10, Script())])
    origin_transactions = [coinbase_0]
    origin_header = BlockHeader("00" * 32,
                                generate_merkle_root(origin_transactions), 0)
    origin = Block(origin_header, origin_transactions)
    blockchain._add_block(origin)

    coinbase_1 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000aa"))],
        [TxOut(5 * 10**9, Script()),
         TxOut(5 * 10**9, Script())],
    )
    tx = Tx(
        [TxIn(OutPoint(coinbase_0.txid, 0), Script())],
        [TxOut(10**10 - 100, Script()),
         TxOut(50, Script())],
    )
    block_1_transactions = [coinbase_1, tx]
    block_1_header = BlockHeader(origin.header.pow,
                                 generate_merkle_root(block_1_transactions), 0)
    block_1 = Block(block_1_header, block_1_transactions)

    coinbase_2 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000bb"))],
        [TxOut(10**10, Script())],
    )
    tx_2 = Tx([TxIn(OutPoint(tx.txid, 0), Script())],
              [TxOut(10**10 - 200, Script())])
    tx_3 = Tx(
        [
            TxIn(OutPoint(coinbase_1.txid, 0), Script()),
            TxIn(OutPoint(coinbase_1.txid, 1), Script()),
            TxIn(OutPoint(tx.txid, 1), Script()),
        ],
        [TxOut(10**10 + 50, Script())],
    )
    block_2_transactions = [coinbase_2, tx_2, tx_3]
    block_2_header = BlockHeader(block_1.header.pow,
                                 generate_merkle_root(block_2_transactions), 0)
    block_2 = Block(block_2_header, block_2_transactions)

    # we try adding the origin again, no problem, it is skipped
    assert blockchain.add_blocks([origin, block_1, block_2])

    coinbase_3 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000cc"))],
        [TxOut(10**10, Script())],
    )
    # tx_4 speds the same inputs as tx_2, but it is in a different chain so it is OK
    tx_4 = Tx(
        [TxIn(OutPoint(tx.txid, 0), Script.from_hex("00030000dd"))],
        [TxOut(10**10 - 200, Script())],
    )
    block_3_transactions = [coinbase_3, tx_4]
    block_3_header = BlockHeader(block_1.header.pow,
                                 generate_merkle_root(block_3_transactions), 0)
    block_3 = Block(block_3_header, block_3_transactions)
    block_3.header.nonce = calculate_nonce(block_3_header, 100)

    coinbase_4 = Tx(
        [TxIn(OutPoint("00" * 32, 0), Script.from_hex("00030000ee"))],
        [TxOut(10**10, Script())],
    )
    block_4_transactions = [coinbase_4]
    # invalid reference, must be block_3 header, not block_2
    block_4_header = BlockHeader(block_2.header.pow,
                                 generate_merkle_root(block_4_transactions), 0)
    block_4 = Block(block_4_header, block_4_transactions)

    assert blockchain.add_blocks([block_3, block_4])
    assert blockchain.get_last_blocks()[0][0] == block_3.header.pow

    block_4.header = BlockHeader(block_3.header.pow,
                                 generate_merkle_root(block_4_transactions), 0)
    assert blockchain.add_blocks([block_3, block_4])
    assert blockchain.get_last_blocks()[0][0] == block_4.header.pow

    reset_blockchain()