Commit Graph

227 Commits

Author SHA1 Message Date
link2xt
170e4b3530 refactor(sql): make open flags immutable 2024-05-14 14:55:04 +00:00
iequidoo
518db9a20f feat: Make one-to-one chats read-only the first seconds of a SecureJoin (#5512)
This protects Bob (the joiner) of sending unexpected-unencrypted messages during an otherwise nicely
running SecureJoin.

If things get stuck, however, we do not want to block communication -- the chat is just
opportunistic as usual, but that needs to be communicated:
1. If Bob's chat with Alice is `Unprotected` and a SecureJoin is started, then add info-message
   "Establishing guaranteed end-to-end encryption, please wait..." and let `Chat::can_send()` return
   `false`.
2. Once the info-message "Messages are guaranteed to be e2ee from now on" is added, let
   `Chat::can_send()` return `true`.
3. If after SECUREJOIN_WAIT_TIMEOUT seconds `2.` did not happen, add another info-message "Could not
   yet establish guaranteed end-to-end encryption but you may already send a message" and also let
   `Chat::can_send()` return `true`.

Both `2.` and `3.` require the event `ChatModified` being sent out so that UI pick up the change wrt
`Chat::can_send()` (this is the same way how groups become updated wrt `can_send()` changes).

SECUREJOIN_WAIT_TIMEOUT should be 10-20 seconds so that we are reasonably sure that the app remains
active and receiving also on mobile devices. If the app is killed during this time then we may need
to do step 3 for any pending Bob-join chats (right now, Bob can only join one chat at a time).
2024-05-13 12:08:36 +02:00
link2xt
6bfbf6547b feat: delete orphaned POI locations during housekeeping 2024-04-29 22:35:59 +00:00
link2xt
34f4ec02f6 feat: replace event channel with broadcast channel
This makes `EventTracker` receive events immediately
instead of being moved from event emitter to event tracker
by a task spawned from `TestContext::new_internal`.

This makes `EventTracker.clear_events` reliable
as it is guaranteed to remove all events emitted
by the time it is called rather than only events
that have been moved already.
2024-04-22 07:44:21 +00:00
B. Petersen
99c4d24eab cleanup jobs and Params relicts
- the `jobs` table is no longer in use,
  no need to track files on housekeeping,
  no need to clear it from repl tool

- some `Params` were used for jobs table only,
  they can be used freely for other purposes on other tables.
  param 'protection settings timestamp' was never used in practise,
  its code is removed as well, so we can free the Param as well.
2024-03-30 08:10:57 +01:00
bjoern
c468eb088e fix: on iOS, use FILE (default) instead of MEMORY (#5349)
this PR fixes one of the issues we had with an (honestly accidentally)
huge database of >2gb.

this database could not be exported on iOS, as ram memory is limited
there, leading to the app just crashing.

it is unclear if that would be better on eg. Android, however,
temp_store=FILE is not working as well there, this is the smaller
drawback there.

before merging, this PR should be tested on time with export/import on
iOS (export/import uses VACUUM which uses /tmp) EDIT: did so, works on
iphone7 with ios15
2024-03-17 08:25:55 +01:00
iequidoo
c0832af634 refactor: Remove deduplicate_peerstates()
There's the `UNIQUE (acpeerstates.addr)` constraint since db v94.
2024-03-08 00:42:39 -03:00
link2xt
2030de11d9 chore: fix 2024-03-05 nightly clippy warnings 2024-03-08 02:53:47 +00:00
iequidoo
6e55f0c6e3 feat: Mock SystemTime::now() for the tests
Add a new crate `deltachat_time` with a fake `struct SystemTimeTools` for mocking
`SystemTime::now()` for test purposes. One still needs to use `std::time::SystemTime` as a struct
representing a system time. I think such a minimalistic approach is ok -- even if somebody uses the
original `SystemTime::now()` instead of the mock by mistake, that could break only tests but not the
program itself. The worst thing that can happen is that tests using `SystemTime::shift()` and
checking messages timestamps f.e. wouldn't catch the corresponding bugs, but now we don't have such
tests at all which is much worse.
2024-02-15 14:24:46 -03:00
iequidoo
b5f2c747e0 feat: Context::set_config(): Restart IO scheduler if needed (#5111)
Restart the IO scheduler if needed to make the new config value effective (for `MvboxMove,
OnlyFetchMvbox, SentboxWatch` currently). Also add `set_config_internal()` which doesn't affect
running the IO scheduler. The reason is that `Scheduler::start()` itself calls `set_config()`,
although not for the mentioned keys, but still, and also Rust complains about recursive async calls.
2024-02-12 15:41:11 -03:00
link2xt
58620988d7 refactor(sql): recreate config table with UNIQUE constraint 2023-12-17 14:13:54 +00:00
link2xt
83d2e6b8b4 fix: do not interrupt IMAP loop from get_connectivity_html()
Android calls get_connectivity_html()
every time connectivity changes, which in turn interrupts
IMAP loop and triggers change from "not connected" to "connecting"
state.

To avoid such infinite loop of IMAP interrupts when
there is not connectivity, update quota only when IMAP
loop is interrupted otherwise. This anyway happens
when a message is received or maybe_network is called.

Also remove outdated comments about `Action::UpdateRecentQuota` job
which does not exist anymore.
2023-10-22 18:48:14 +00:00
link2xt
64035d3ecb fix: set soft_heap_limit on SQLite database
This should prevent unlimited growth of memory usage
by SQLite for is page cache.
2023-10-20 05:18:21 +00:00
link2xt
67043177a9 fix: reopen all connections on database passpharse change
Previously only one connection, the one used to change the key,
was working after passphrase change.

With this fix the whole pool of connections
is recreated on passphrase change, so there is no need
to reopen the database manually.
2023-09-12 16:34:26 +00:00
link2xt
cd477936b5 api: add dc_context_change_passphrase() 2023-09-05 12:41:31 +00:00
B. Petersen
d572d960e5 delete old webxdc status updates during housekeeping 2023-07-23 09:16:28 +00:00
link2xt
9c68fac4b6 api!: make Message.text non-optional
Message.set_text() and Message.get_text() are modified accordingly
to accept String and return String.

Messages which previously contained None text
are now represented as messages with empty text.
Use Message.set_text("".to_string())
instead of Message.set_text(None).
2023-07-03 15:36:32 +00:00
link2xt
619b849ce7 sql: cleanup usage of ToSql
Moved custom ToSql trait including Send + Sync from lib.rs to sql.rs.
Replaced most params! and paramsv! macro usage with tuples.

Replaced paramsv! and params_iterv! with params_slice!,
because there is no need to construct a vector.
2023-04-13 12:48:00 +00:00
Floris Bruynooghe
2469964a44 ref(sql): Do not warn if BLOBS_BACKUP_NAME does not exist (#4256)
ref(sql): Dop not warn if BLOBS_BACKUP_NAME does not exist

It is perfectly normal for this directory to not exist.
2023-04-03 09:28:17 +02:00
iequidoo
c401780c15 Compress mime_headers column with HTML emails stored in database (#4077)
Co-authored-by: bjoern <r10s@b44t.com>
2023-03-31 19:45:34 -03:00
Floris Bruynooghe
82ace72527 ref(logging): Remove message from LogExt::log_err (#4235)
This removes the message that needed to be supplied to LogExt::log_err
calls.  This was from a time before we adopted anyhow and now we are
better off using anyhow::Context::context for the message: it is more
consistent, composes better and is less custom.

The benefit of the composition can be seen in the FFI calls which need
to both log the error as well as return it to the caller via
the set_last_error mechanism.

It also removes the LogExt::ok_or_log_msg funcion for the same reason,
the message is obsoleted by anyhow's context.
2023-03-30 10:13:07 +02:00
link2xt
83af248068 Turn more log messages into proper sentences. 2023-03-24 12:15:42 +00:00
Hocuri
8302d22622 Improve comment on write_lock() (#4134) 2023-03-21 11:49:14 +01:00
link2xt
f024909611 sql: replace empty paramsv![] with empty tuples 2023-03-15 22:20:40 +00:00
link2xt
8db64726ea sql: expect zero-column results from PRAGMA incremental_vacuum
The fact that `PRAGMA incremental_vacuum` may return a zero-column
SQLITE_ROW result is documented in `sqlite3_data_count()` documentation:
<https://www.sqlite.org/c3ref/data_count.html>

Previously successful auto_vacuum worked,
but resulted in a "Failed to run incremental vacuum" log.
2023-03-15 21:15:46 +00:00
link2xt
7e5a8714a0 Add scripts/codespell.sh and spellcheck 2023-03-03 18:40:36 +00:00
iequidoo
627cf20074 Housekeeping: delete the blobs backup dir (#4104) 2023-03-03 11:06:41 -03:00
iequidoo
e767d84bea Switch to DEFERRED transactions
We do not make all transactions
[IMMEDIATE](https://www.sqlite.org/lang_transaction.html#deferred_immediate_and_exclusive_transactions)
for more parallelism -- at least read transactions can be made DEFERRED to run in parallel
w/o any drawbacks. But if we make write transactions DEFERRED also w/o any external locking,
then they are upgraded from read to write ones on the first write statement. This has some
drawbacks:
- If there are other write transactions, we block the thread and the db connection until
  upgraded. Also if some reader comes then, it has to get next, less used connection with a
  worse per-connection page cache.
- If a transaction is blocked for more than busy_timeout, it fails with SQLITE_BUSY.
- Configuring busy_timeout is not the best way to manage transaction timeouts, we would
  prefer it to be integrated with Rust/tokio asyncs. Moreover, SQLite implements waiting
  using sleeps.
- If upon a successful upgrade to a write transaction the db has been modified by another
  one, the transaction has to be rolled back and retried. It is an extra work in terms of
  CPU/battery.
- Maybe minor, but we lose some fairness in servicing write transactions, i.e. we service
  them in the order of the first write statement, not in the order they come.
The only pro of making write transactions DEFERRED w/o the external locking is some
parallelism between them. Also we have an option to make write transactions IMMEDIATE, also
w/o the external locking. But then the most of cons above are still valid. Instead, if we
perform all write transactions under an async mutex, the only cons is losing some
parallelism for write transactions.
2023-02-28 15:05:47 -03:00
link2xt
064f806d90 Remove UpdateRecentQuota job 2023-02-24 17:49:08 +00:00
Hocuri
17acbca576 Correctly clear database cache after import (#4067) 2023-02-21 11:23:34 +00:00
link2xt
92c7cc40d4 sql: replace .get_conn() interface with .call()
.call() interface is safer because it ensures
that blocking operations on SQL connection
are called within tokio::task::block_in_place().

Previously some code called blocking operations
in async context, e.g. add_parts() in receive_imf module.

The underlying implementation of .call()
can later be replaced with an implementation
that does not require block_in_place(),
e.g. a worker pool,
without changing the code using the .call() interface.
2023-02-20 18:54:29 +00:00
link2xt
eaa2ef5a44 sql: start transactions as IMMEDIATE
With the introduction of transactions in Contact::add_or_lookup(),
python tests sometimes fail to create contacts with the folowing error:

Cannot create contact: add_or_lookup: database is locked: Error code 5: The database file is locked

`PRAGMA busy_timeout=60000` does not affect
this case as the error is returned before 60 seconds pass.

DEFERRED transactions with write operations need
to be retried from scratch
if they are rolled back
due to a write operation on another connection.

Using IMMEDIATE transactions for writing
is an attempt to fix this problem
without a retry loop.

If we later need DEFERRED transactions,
e.g. for reading a snapshot without locking the database,
we may introduce another function for this.
2023-02-20 15:05:35 +00:00
link2xt
10066b2bc7 sql: use semaphore to limit access to the connection pool
This ensures that if multiple connections are returned
to the pool at the same time, waiters get them in the order
they were placed in the queue.
2023-02-19 17:06:25 +00:00
link2xt
75f65b06e8 Run VACUUM on the same connection as sqlcipher_export
Otherwise export_and_import_backup test fails due to SQLITE_SCHEMA error.
2023-02-19 02:26:26 +00:00
link2xt
f2b05ccc29 Reimplement connection pool on top of crossbeam 2023-02-19 02:26:26 +00:00
link2xt
ed8e2c4818 Replace r2d2 with an own connection pool
New connection pool does not use threads
and does not remove idle connections
or create new connections at runtime.
2023-02-19 02:26:26 +00:00
link2xt
870527de1e Remove r2d2_sqlite dependency 2023-02-17 11:06:17 +00:00
link2xt
a34aeb240a Increase database timeout to 60 seconds 2023-02-16 18:37:47 +00:00
link2xt
ae19c9b331 Add more documentation 2023-02-15 21:56:33 +00:00
link2xt
7d2cca8633 sql: enable auto_vacuum on all connections 2023-02-15 18:59:47 +00:00
link2xt
fcf73165ed Inline format arguments
This feature has been stable since Rust 1.58.0.
2023-01-30 11:50:11 +03:00
link2xt
ba3e4c5dff Resultify tools::delete_file() 2023-01-29 00:35:15 +00:00
Sebastian Klähn
ba860a2b61 Debug logging v2 (#3958)
debug logging
2023-01-25 13:22:15 +00:00
link2xt
4615c84f31 Automatically group imports using nightly rustfmt 2023-01-19 13:13:25 +00:00
link2xt
754c7324f5 Print more anyhow errors with their causes 2023-01-05 21:21:42 +00:00
iequidoo
c3a0bb2b77 Fix cargo clippy and doc errors after Rust update to 1.66 2022-12-16 02:46:04 +04:00
link2xt
2cd63234c1 Do not allow missing documentation by default 2022-12-13 23:45:12 +00:00
Hocuri
6c4d919828 Add members to chats in a single sql transation (#3780)
This esp. speeds up receive_imf a bit when we recreate the member list (recreate_member_list == true).

It's a preparation for https://github.com/deltachat/deltachat-core-rust/issues/3768, which will be a one-line-fix, but recreate the member list more often, so that we want to optimize this case a bit.

It also adds a benchmark for this case. It's not that easy to make the benchmark non-flaky, but by closing all other programs and locking the CPU to 1.5GHz it worked. It is consistently a few percent faster than ./without-optim:

```
Receive messages/Receive 100 Chat-Group-Member-{Added|Removed} messages                                                                            
                        time:   [52.257 ms 52.569 ms 52.941 ms]
                        change: [-3.5301% -2.6181% -1.6697%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  4 (4.00%) high mild
  3 (3.00%) high severe
```
2022-11-29 19:37:56 +00:00
iequidoo
f6a502a8e3 Remove the remaining AsRef<str> (#3669)
Using &str instead of AsRef is better for compile times, binary size and code complexity.
2022-11-28 17:02:05 -03:00
link2xt
c7691fbebe Use UPSERT when saving peerstates
This way there is no need to distinguish between creating
and updating peerstate.
2022-11-27 17:10:46 +00:00