feat: start implementing hashes in shared lib and refactoring

This commit is contained in:
0x330a 2023-02-27 13:12:01 +11:00
parent c36387175d
commit c06c7eab19
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
6 changed files with 58 additions and 21 deletions

View File

@ -18,7 +18,7 @@ class ConfigDatabase(context: Context, helper: SQLCipherOpenHelper): Database(co
const val CREATE_CONFIG_TABLE_COMMAND = const val CREATE_CONFIG_TABLE_COMMAND =
"CREATE TABLE $TABLE_NAME ($VARIANT TEXT NOT NULL, $PUBKEY TEXT NOT NULL, $DATA BLOB, $COMBINED_MESSAGE_HASHES TEXT, PRIMARY KEY($VARIANT, $PUBKEY));" "CREATE TABLE $TABLE_NAME ($VARIANT TEXT NOT NULL, $PUBKEY TEXT NOT NULL, $DATA BLOB, $COMBINED_MESSAGE_HASHES TEXT, PRIMARY KEY($VARIANT, $PUBKEY));"
private const val VARIANT_WHERE = "$VARIANT = ?"
private const val VARIANT_AND_PUBKEY_WHERE = "$VARIANT = ? AND $PUBKEY = ?" private const val VARIANT_AND_PUBKEY_WHERE = "$VARIANT = ? AND $PUBKEY = ?"
} }

@ -1 +1 @@
Subproject commit 4930086a348d175cff4a41e804c84f23d048951e Subproject commit c76d7e06f6c1c258fe930bcd8d567b3bd4067262

View File

@ -23,10 +23,12 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_needsDump(JNIEnv *env, j
JNIEXPORT jobject JNICALL JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobject thiz) { Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobject thiz) {
auto config = ptrToConfigBase(env, thiz); auto config = ptrToConfigBase(env, thiz);
auto pair = config->push(); auto push_tuple = config->push();
session::ustring to_push_str = pair.first; auto to_push_str = std::get<1>(push_tuple);
auto to_delete = std::get<2>(push_tuple);
jbyteArray returnByteArray = util::bytes_from_ustring(env, to_push_str); jbyteArray returnByteArray = util::bytes_from_ustring(env, to_push_str);
jlong seqNo = pair.second; jlong seqNo = std::get<0>(push_tuple);
jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/ConfigWithSeqNo"); jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/ConfigWithSeqNo");
jmethodID methodId = env->GetMethodID(returnObjectClass, "<init>", "([BJ)V"); jmethodID methodId = env->GetMethodID(returnObjectClass, "<init>", "([BJ)V");
jobject returnObject = env->NewObject(returnObjectClass, methodId, returnByteArray, seqNo); jobject returnObject = env->NewObject(returnObjectClass, methodId, returnByteArray, seqNo);
@ -56,34 +58,38 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_encryptionDomain(JNIEnv
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_confirmPushed(JNIEnv *env, jobject thiz, Java_network_loki_messenger_libsession_1util_ConfigBase_confirmPushed(JNIEnv *env, jobject thiz,
jlong seq_no) { jlong seq_no,
jstring new_hash_jstring) {
auto conf = ptrToConfigBase(env, thiz); auto conf = ptrToConfigBase(env, thiz);
conf->confirm_pushed(seq_no); auto new_hash = env->GetStringUTFChars(new_hash_jstring, nullptr);
conf->confirm_pushed(seq_no, new_hash);
env->ReleaseStringUTFChars(new_hash_jstring, new_hash);
} }
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma ide diagnostic ignored "bugprone-reserved-identifier" #pragma ide diagnostic ignored "bugprone-reserved-identifier"
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3_3B(JNIEnv *env, jobject thiz, Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3Lkotlin_Pair_2(JNIEnv *env, jobject thiz,
jobjectArray to_merge) { jobjectArray to_merge) {
auto conf = ptrToConfigBase(env, thiz); auto conf = ptrToConfigBase(env, thiz);
size_t number = env->GetArrayLength(to_merge); size_t number = env->GetArrayLength(to_merge);
std::vector<session::ustring> configs = {}; std::vector<std::pair<std::string,session::ustring>> configs = {};
for (int i = 0; i < number; i++) { for (int i = 0; i < number; i++) {
auto jArr = (jbyteArray) env->GetObjectArrayElement(to_merge, i); auto jElement = (jobject) env->GetObjectArrayElement(to_merge, i);
auto bytes = util::ustring_from_bytes(env, jArr); auto pair = extractHashAndData(env, jElement);
configs.push_back(bytes); configs.push_back(pair);
} }
return conf->merge(configs); return conf->merge(configs);
} }
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_merge___3B(JNIEnv *env, jobject thiz, Java_network_loki_messenger_libsession_1util_ConfigBase_merge__Lkotlin_Pair_2(JNIEnv *env, jobject thiz,
jbyteArray to_merge) { jobject to_merge) {
auto conf = ptrToConfigBase(env, thiz); auto conf = ptrToConfigBase(env, thiz);
std::vector<session::ustring> configs = {util::ustring_from_bytes(env, to_merge)}; std::vector<std::pair<std::string, session::ustring>> configs = {extractHashAndData(env, to_merge)};
return conf->merge(configs); return conf->merge(configs);
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop
} }
extern "C" extern "C"
@ -100,6 +106,7 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(J
auto user_class = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); auto user_class = env->FindClass("network/loki/messenger/libsession_util/UserProfile");
auto contact_class = env->FindClass("network/loki/messenger/libsession_util/Contacts"); auto contact_class = env->FindClass("network/loki/messenger/libsession_util/Contacts");
auto convo_volatile_class = env->FindClass("network/loki/messenger/libsession_util/ConversationVolatileConfig"); auto convo_volatile_class = env->FindClass("network/loki/messenger/libsession_util/ConversationVolatileConfig");
auto group_list_class = env->FindClass("network/loki/messenger/libsession_util/UserGroupsConfig");
switch (config_namespace) { switch (config_namespace) {
case (int)session::config::Namespace::UserProfile: case (int)session::config::Namespace::UserProfile:
return user_class; return user_class;
@ -107,7 +114,23 @@ Java_network_loki_messenger_libsession_1util_ConfigBase_00024Companion_kindFor(J
return contact_class; return contact_class;
case (int)session::config::Namespace::ConvoInfoVolatile: case (int)session::config::Namespace::ConvoInfoVolatile:
return convo_volatile_class; return convo_volatile_class;
case (int)session::config::Namespace::UserGroups:
return group_list_class;
default: default:
return nullptr; return nullptr;
} }
} }
extern "C"
JNIEXPORT void JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_removeObsoleteHashes(JNIEnv *env,
jobject thiz,
jobjectArray to_remove) {
auto conf = ptrToConfigBase(env, thiz);
size_t number = env->GetArrayLength(to_remove);
for (int i = 0; i < number; i++) {
auto jElement = (jstring) env->GetObjectArrayElement(to_remove, i);
auto element_as_string = env->GetStringUTFChars(jElement, nullptr);
conf->confirm_removed(element_as_string);
env->ReleaseStringUTFChars(jElement, element_as_string);
}
}

View File

@ -2,6 +2,7 @@
#define SESSION_ANDROID_CONFIG_BASE_H #define SESSION_ANDROID_CONFIG_BASE_H
#include "session/config/base.hpp" #include "session/config/base.hpp"
#include "util.h"
#include <jni.h> #include <jni.h>
#include <string> #include <string>
@ -11,4 +12,17 @@ inline session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) {
return (session::config::ConfigBase*) env->GetLongField(obj, pointerField); return (session::config::ConfigBase*) env->GetLongField(obj, pointerField);
} }
inline std::pair<std::string, session::ustring> extractHashAndData(JNIEnv *env, jobject kotlin_pair) {
jclass pair = env->FindClass("kotlin/Pair");
jfieldID first = env->GetFieldID(pair, "first", "Ljava/lang/Object;");
jfieldID second = env->GetFieldID(pair, "second", "Ljava/lang/Object;");
jstring hash_as_jstring = static_cast<jstring>(env->GetObjectField(kotlin_pair, first));
jbyteArray data_as_jbytes = static_cast<jbyteArray>(env->GetObjectField(kotlin_pair, second));
auto hash_as_string = env->GetStringUTFChars(hash_as_jstring, nullptr);
auto data_as_ustring = util::ustring_from_bytes(env, data_as_jbytes);
auto ret_pair = std::pair<std::string, session::ustring>{hash_as_string, data_as_ustring};
env->ReleaseStringUTFChars(hash_as_jstring, hash_as_string);
return ret_pair;
}
#endif #endif

View File

@ -31,13 +31,14 @@ sealed class ConfigBase(protected val /* yucky */ pointer: Long) {
external fun push(): ConfigWithSeqNo external fun push(): ConfigWithSeqNo
external fun dump(): ByteArray external fun dump(): ByteArray
external fun encryptionDomain(): String external fun encryptionDomain(): String
external fun confirmPushed(seqNo: Long) external fun confirmPushed(seqNo: Long, newHash: String)
external fun merge(toMerge: Array<ByteArray>): Int external fun merge(toMerge: Array<Pair<String,ByteArray>>): Int
external fun removeObsoleteHashes(toRemove: Array<String>)
external fun configNamespace(): Int external fun configNamespace(): Int
// Singular merge // Singular merge
external fun merge(toMerge: ByteArray): Int external fun merge(toMerge: Pair<String,ByteArray>): Int
external fun free() external fun free()

View File

@ -136,13 +136,12 @@ data class ConfigurationSyncJob(val destination: Destination): Job {
// confirm pushed seqno // confirm pushed seqno
val thisSeqNo = toPushMessage.seqNo val thisSeqNo = toPushMessage.seqNo
config.confirmPushed(thisSeqNo) config.confirmPushed(thisSeqNo, insertHash)
config.
// wipe any of the existing hashes which we deleted (they may or may not be in this namespace) // wipe any of the existing hashes which we deleted (they may or may not be in this namespace)
if (configFactory.removeHashesFor(config, deletedHashes.toSet())) { if (configFactory.removeHashesFor(config, deletedHashes.toSet())) {
Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}") Log.d(TAG, "Successfully removed the deleted hashes from ${config.javaClass.simpleName}")
} }
// store the new hash in list of hashes to track against
configFactory.appendHash(config, insertHash)
// dump and write config after successful // dump and write config after successful
if (config.needsDump()) { // usually this will be true? if (config.needsDump()) { // usually this will be true?
configFactory.persist(config) configFactory.persist(config)