def test_table_paymentrequests_crud(db_context: DatabaseContext) -> None: table = PaymentRequestTable(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 = PaymentRequestRow(1, KEYINSTANCE_ID, PaymentState.PAID, None, None, "desc", table._get_current_timestamp()) line2 = PaymentRequestRow(2, KEYINSTANCE_ID + 1, PaymentState.UNPAID, 100, 60 * 60, None, table._get_current_timestamp()) # No effect: The transactionoutput foreign key constraint will fail as the key instance # 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 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([ (PaymentState.UNKNOWN, 20, 999, "newdesc", line2.paymentrequest_id) ], 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.paymentrequest_id == line2.paymentrequest_id ][0] assert db_line2.value == 20 assert db_line2.state == PaymentState.UNKNOWN assert db_line2.description == "newdesc" assert db_line2.expiration == 999 # Account does not exist. db_lines = table.read(1000) assert 0 == len(db_lines) # This account is matched. db_lines = table.read(ACCOUNT_ID) assert 2 == len(db_lines) with SynchronousWriter() as writer: table.delete([(line2.paymentrequest_id, )], completion_callback=writer.get_callback()) assert writer.succeeded() db_lines = table.read() assert 1 == len(db_lines) assert db_lines[0].paymentrequest_id == line1.paymentrequest_id
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]
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")
def test_table_keyinstances_crud(db_context: DatabaseContext) -> None: table = KeyInstanceTable(db_context) assert [] == table.read() table._get_current_timestamp = lambda: 10 KEYINSTANCE_ID = 0 ACCOUNT_ID = 10 MASTERKEY_ID = 20 DERIVATION_DATA1 = b'111' DERIVATION_DATA2 = b'222' SCRIPT_TYPE = 40 line1 = KeyInstanceRow(KEYINSTANCE_ID + 1, ACCOUNT_ID + 1, MASTERKEY_ID + 1, DerivationType.BIP32, DERIVATION_DATA1, SCRIPT_TYPE + 1, True, None) line2 = KeyInstanceRow(KEYINSTANCE_ID + 2, ACCOUNT_ID + 1, MASTERKEY_ID + 1, DerivationType.HARDWARE, DERIVATION_DATA2, SCRIPT_TYPE + 2, True, None) # No effect: The masterkey foreign key constraint will fail as the masterkey 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 masterkey foreign key constraint by creating the masterkey. mktable = MasterKeyTable(db_context) with SynchronousWriter() as writer: mktable.create([MasterKeyRow(MASTERKEY_ID + 1, None, 2, b'111')], completion_callback=writer.get_callback()) assert writer.succeeded() # No effect: The account foreign key constraint will fail as the account 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 account foreign key constraint by creating the account. acctable = AccountTable(db_context) with SynchronousWriter() as writer: acctable.create([ AccountRow(ACCOUNT_ID + 1, MASTERKEY_ID + 1, ScriptType.P2PKH, 'name') ], 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[0] == line1[0]][0] assert line1 == db_line1 db_line2 = [db_line for db_line in db_lines if db_line[0] == line2[0]][0] assert line2 == db_line2 date_updated = 20 with SynchronousWriter() as writer: table.update_derivation_data([(b'234', line1[0])], date_updated, completion_callback=writer.get_callback()) assert writer.succeeded() with SynchronousWriter() as writer: table.update_flags([(False, line2[0])], 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] == line1[0]][0] assert b'234' == db_line1[4] db_line2 = [db_line for db_line in db_lines if db_line[0] == line2[0]][0] assert not db_line2[6] with SynchronousWriter() as writer: table.delete([line2[0]], completion_callback=writer.get_callback()) assert writer.succeeded() db_lines = table.read() assert 1 == len(db_lines) assert db_lines[0].keyinstance_id == line1.keyinstance_id assert db_lines[0].description is None # Now try out the labels. with SynchronousWriter() as writer: table.update_descriptions([("line1", line1.keyinstance_id)], completion_callback=writer.get_callback()) assert writer.succeeded() rows = table.read() assert len(rows) == 1 assert rows[0].keyinstance_id == line1[0] assert rows[0].description == "line1"