Exemplo n.º 1
0
def test_table_transactionoutputs_crud(db_context: DatabaseContext) -> None:
    table = TransactionOutputTable(db_context)
    assert [] == table.read()

    table._get_current_timestamp = lambda: 10

    TX_BYTES = os.urandom(10)
    TX_HASH = bitcoinx.double_sha256(TX_BYTES)
    TX_INDEX = 1
    TXOUT_FLAGS = 1 << 15
    KEYINSTANCE_ID = 1
    ACCOUNT_ID = 10
    MASTERKEY_ID = 20
    DERIVATION_DATA1 = b'111'
    DERIVATION_DATA2 = b'222'
    SCRIPT_TYPE = 40

    line1 = (TX_HASH, TX_INDEX, 100, KEYINSTANCE_ID, TXOUT_FLAGS)
    line2 = (TX_HASH, TX_INDEX + 1, 200, KEYINSTANCE_ID, TXOUT_FLAGS)

    # No effect: The transactionoutput foreign key constraint will fail as the transactionoutput
    # does not exist.
    with pytest.raises(sqlite3.IntegrityError):
        with SynchronousWriter() as writer:
            table.create([line1], completion_callback=writer.get_callback())
            assert not writer.succeeded()

    # Satisfy the transaction foreign key constraint by creating the transaction.
    transaction_table = TransactionTable(db_context)
    with SynchronousWriter() as writer:
        transaction_table.create(
            [(TX_HASH,
              TxData(
                  height=1, fee=2, position=None, date_added=1,
                  date_updated=1), TX_BYTES,
              TxFlags.HasByteData | TxFlags.HasFee | TxFlags.HasHeight, None)],
            completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Satisfy the masterkey foreign key constraint by creating the masterkey.
    masterkey_table = MasterKeyTable(db_context)
    with SynchronousWriter() as writer:
        masterkey_table.create([(MASTERKEY_ID, None, 2, b'111')],
                               completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Satisfy the account foreign key constraint by creating the account.
    account_table = AccountTable(db_context)
    with SynchronousWriter() as writer:
        account_table.create(
            [(ACCOUNT_ID, MASTERKEY_ID, ScriptType.P2PKH, 'name')],
            completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Satisfy the keyinstance foreign key constraint by creating the keyinstance.
    keyinstance_table = KeyInstanceTable(db_context)
    with SynchronousWriter() as writer:
        keyinstance_table.create(
            [(KEYINSTANCE_ID, ACCOUNT_ID, MASTERKEY_ID, DerivationType.BIP32,
              DERIVATION_DATA1, SCRIPT_TYPE, True, None)],
            completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Create the first row.
    with SynchronousWriter() as writer:
        table.create([line1], completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Create the second row.
    with SynchronousWriter() as writer:
        table.create([line2], completion_callback=writer.get_callback())
        assert writer.succeeded()

    # No effect: The primary key constraint will prevent any conflicting entry from being added.
    with pytest.raises(sqlite3.IntegrityError):
        with SynchronousWriter() as writer:
            table.create([line1], completion_callback=writer.get_callback())
            assert not writer.succeeded()

    db_lines = table.read()
    assert 2 == len(db_lines)
    db_line1 = [db_line for db_line in db_lines if db_line == line1][0]
    assert line1 == db_line1
    db_line2 = [db_line for db_line in db_lines if db_line == line2][0]
    assert line2 == db_line2

    date_updated = 20

    with SynchronousWriter() as writer:
        table.update_flags(
            [(TransactionOutputFlag.IS_SPENT, line2[0], line2[1])],
            date_updated,
            completion_callback=writer.get_callback())
        assert writer.succeeded()

    db_lines = table.read()
    assert 2 == len(db_lines)
    db_line1 = [db_line for db_line in db_lines
                if db_line[0:2] == line1[0:2]][0]
    db_line2 = [db_line for db_line in db_lines
                if db_line[0:2] == line2[0:2]][0]
    assert db_line2.flags == TransactionOutputFlag.IS_SPENT

    db_lines = table.read(mask=~TransactionOutputFlag.IS_SPENT)
    assert 1 == len(db_lines)
    assert db_lines[0].flags & TransactionOutputFlag.IS_SPENT == 0

    db_lines = table.read(mask=TransactionOutputFlag.IS_SPENT)
    assert 1 == len(db_lines)
    assert db_lines[
        0].flags & TransactionOutputFlag.IS_SPENT == TransactionOutputFlag.IS_SPENT

    with SynchronousWriter() as writer:
        table.delete([line2[0:2]], completion_callback=writer.get_callback())
        assert writer.succeeded()

    db_lines = table.read()
    assert 1 == len(db_lines)
    assert db_lines[0][0:2] == line1[0:2]
Exemplo n.º 2
0
def test_table_transactiondeltas_crud(db_context: DatabaseContext) -> None:
    table = TransactionDeltaTable(db_context)
    assert [] == table.read()

    table._get_current_timestamp = lambda: 10

    TX_BYTES = os.urandom(10)
    TX_HASH = bitcoinx.double_sha256(TX_BYTES)
    TX_INDEX = 1
    TXOUT_FLAGS = 1 << 15
    KEYINSTANCE_ID = 1
    ACCOUNT_ID = 10
    MASTERKEY_ID = 20
    DERIVATION_DATA = b'111'
    SCRIPT_TYPE = 40

    TX_BYTES2 = os.urandom(10)
    TX_HASH2 = bitcoinx.double_sha256(TX_BYTES2)

    LINE_COUNT = 3
    line1 = TransactionDeltaRow(TX_HASH, KEYINSTANCE_ID, 100)
    line2 = TransactionDeltaRow(TX_HASH, KEYINSTANCE_ID + 1, 100)

    # No effect: The transactionoutput foreign key constraint will fail as the transactionoutput
    # does not exist.
    with pytest.raises(sqlite3.IntegrityError):
        with SynchronousWriter() as writer:
            table.create([line1], completion_callback=writer.get_callback())
            assert not writer.succeeded()

    # Satisfy the transaction foreign key constraint by creating the transaction.
    transaction_table = TransactionTable(db_context)
    with SynchronousWriter() as writer:
        transaction_table.create(
            [(TX_HASH,
              TxData(
                  height=1, fee=2, position=None, date_added=1,
                  date_updated=1), TX_BYTES, TxFlags.HasByteData
              | TxFlags.HasFee | TxFlags.HasHeight, "tx 1"),
             (TX_HASH2,
              TxData(
                  height=1, fee=2, position=None, date_added=1,
                  date_updated=1), TX_BYTES2,
              TxFlags.HasByteData | TxFlags.HasFee | TxFlags.HasHeight, None)],
            completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Satisfy the masterkey foreign key constraint by creating the masterkey.
    masterkey_table = MasterKeyTable(db_context)
    with SynchronousWriter() as writer:
        masterkey_table.create([(MASTERKEY_ID, None, 2, b'111')],
                               completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Satisfy the account foreign key constraint by creating the account.
    account_table = AccountTable(db_context)
    with SynchronousWriter() as writer:
        account_table.create(
            [(ACCOUNT_ID, MASTERKEY_ID, ScriptType.P2PKH, 'name')],
            completion_callback=writer.get_callback())
        assert writer.succeeded()

    # Satisfy the keyinstance foreign key constraint by creating the keyinstance.
    keyinstance_table = KeyInstanceTable(db_context)
    with SynchronousWriter() as writer:
        entries = [
            (KEYINSTANCE_ID + i, ACCOUNT_ID, MASTERKEY_ID,
             DerivationType.BIP32, DERIVATION_DATA, SCRIPT_TYPE, True, None)
            for i in range(LINE_COUNT)
        ]
        keyinstance_table.create(entries,
                                 completion_callback=writer.get_callback())
        assert writer.succeeded()

    with SynchronousWriter() as writer:
        table.create([line1, line2], completion_callback=writer.get_callback())
        assert writer.succeeded()

    # No effect: The primary key constraint will prevent any conflicting entry from being added.
    with pytest.raises(sqlite3.IntegrityError):
        with SynchronousWriter() as writer:
            table.create([line1], completion_callback=writer.get_callback())
            assert not writer.succeeded()

    db_lines = table.read()
    assert 2 == len(db_lines)
    db_line1 = [db_line for db_line in db_lines if db_line == line1][0]
    assert line1 == db_line1
    db_line2 = [db_line for db_line in db_lines if db_line == line2][0]
    assert line2 == db_line2

    date_updated = 20

    with SynchronousWriter() as writer:
        table.update([(20, line2[0], line2[1])],
                     date_updated,
                     completion_callback=writer.get_callback())
        assert writer.succeeded()

    db_lines = table.read()
    assert 2 == len(db_lines)
    db_line2 = [db_line for db_line in db_lines
                if db_line[0:2] == line2[0:2]][0]
    assert db_line2[2] == 20

    line2_delta = TransactionDeltaRow(line2.tx_hash, line2.keyinstance_id, 200)
    line3 = TransactionDeltaRow(TX_HASH, KEYINSTANCE_ID + 2, 999)
    with SynchronousWriter() as writer:
        table.create_or_update_relative_values(
            [line2_delta, line3], completion_callback=writer.get_callback())
        assert writer.succeeded()

    db_lines = table.read()
    assert 3 == len(db_lines)
    db_line2 = [db_line for db_line in db_lines
                if db_line[0:2] == line2[0:2]][0]
    assert db_line2[2] == 20 + 200
    db_line3 = [db_line for db_line in db_lines
                if db_line[0:2] == line3[0:2]][0]
    assert db_line3[2] == line3[2]

    with SynchronousWriter() as writer:
        table.delete([line2[0:2], line3[0:2]],
                     completion_callback=writer.get_callback())
        assert writer.succeeded()

    db_lines = table.read()
    assert 1 == len(db_lines)
    assert db_lines[0][0:2] == line1[0:2]

    drows = table.read_descriptions(ACCOUNT_ID)
    assert len(drows) == 1
    assert drows[0] == (TX_HASH, "tx 1")
Exemplo n.º 3
0
    def setup_class(cls):
        cls.db_context = _db_context()
        cls.store = TransactionTable(cls.db_context)

        cls.tx_hash = os.urandom(32)