Skip to content
This repository was archived by the owner on Feb 12, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions core/src/wallet/common/synchronizers/SavedStateProvider.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <memory>
#include <preferences/Preferences.hpp>
#include <utils/Option.hpp>

namespace ledger::core {
template <typename SavedStateType>
class SavedStateProvider {
public:
explicit SavedStateProvider(std::shared_ptr<Preferences> subPreferences) : _subPreferences{std::move(subPreferences)} {}
Option<SavedStateType> getSavedState() const {
return _subPreferences->getObject<SavedStateType>("state");
}
void setSavedState(SavedStateType &savedState) {
_subPreferences->editor()->putObject<SavedStateType>("state", savedState)->commit();
}

private:
std::shared_ptr<Preferences> _subPreferences;
};
} // namespace ledger::core
4 changes: 4 additions & 0 deletions core/src/wallet/ripple/RippleLikeAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ namespace ledger {
// Clear synchronizer state
eraseSynchronizerDataSince(sql, date);

// Update block height in internal preferences
auto selfPtr = std::static_pointer_cast<RippleLikeAccount>(shared_from_this());
_synchronizer->eraseDataSince(sql, date, selfPtr);

auto accountUid = getAccountUid();
RippleLikeTransactionDatabaseHelper::eraseDataSince(sql, accountUid, date);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
namespace ledger {
namespace core {

constexpr auto subPreferencesPrefix = "RippleLikeAccountSynchronizer";

namespace {

void initializeSavedState(
Expand Down Expand Up @@ -87,7 +89,7 @@ namespace ledger {
RippleLikeAccountSynchronizer::RippleLikeAccountSynchronizer(
const std::shared_ptr<WalletPool> &pool,
const std::shared_ptr<RippleLikeBlockchainExplorer> &explorer)
: DedicatedContext(pool->getDispatcher()->getThreadPoolExecutionContext("synchronizers")), _explorer(explorer) {}
: DedicatedContext(pool->getDispatcher()->getThreadPoolExecutionContext("synchronizers")), _explorer(explorer), _savedStateProvider{} {}

std::shared_ptr<ProgressNotifier<AccountSynchronizationContext>>
RippleLikeAccountSynchronizer::synchronizeAccount(const std::shared_ptr<RippleLikeAccount> &account) {
Expand Down Expand Up @@ -119,7 +121,7 @@ namespace ledger {
buddy->account = account;
buddy->preferences = std::static_pointer_cast<AbstractAccount>(account)
->getInternalPreferences()
->getSubPreferences("RippleLikeAccountSynchronizer");
->getSubPreferences(subPreferencesPrefix);
auto loggerPurpose = fmt::format("synchronize_{}", account->getAccountUid());
auto tracePrefix = fmt::format(
"{}/{}/{}",
Expand Down Expand Up @@ -553,5 +555,38 @@ namespace ledger {
}
}

Option<AccountSynchronizationSavedState> RippleLikeAccountSynchronizer::getSavedState(const std::shared_ptr<RippleLikeAccount> &account) {
return getSavedStateProvider(account)->getSavedState();
}

void RippleLikeAccountSynchronizer::setSavedState(const std::shared_ptr<RippleLikeAccount> &account, AccountSynchronizationSavedState &savedState) {
getSavedStateProvider(account)->setSavedState(savedState);
}

void RippleLikeAccountSynchronizer::eraseDataSince(soci::session &sql, const std::chrono::system_clock::time_point &date, const std::shared_ptr<RippleLikeAccount> &account) {
auto savedState = getSavedState(account);
if (savedState.nonEmpty()) {
// Reset batches to blocks mined before given date
auto previousBlock = BlockDatabaseHelper::getPreviousBlockInDatabase(sql, account->getWallet()->getCurrency().name, date);
for (auto &batch : savedState.getValue().batches) {
if (previousBlock.nonEmpty() && batch.blockHeight > previousBlock.getValue().height) {
batch.blockHeight = static_cast<uint32_t>(previousBlock.getValue().height);
batch.blockHash = previousBlock.getValue().blockHash;
} else if (!previousBlock.nonEmpty()) { // if no previous block, sync should go back from genesis block
batch.blockHeight = 0;
batch.blockHash = "";
}
}
setSavedState(account, savedState.getValue());
}
}

std::unique_ptr<RippleLikeAccountSynchronizer::SavedStateProviderType> RippleLikeAccountSynchronizer::getSavedStateProvider(const std::shared_ptr<RippleLikeAccount> &account) {
auto subPreferences = std::static_pointer_cast<AbstractAccount>(account)
->getInternalPreferences()
->getSubPreferences(subPreferencesPrefix);
return std::make_unique<SavedStateProviderType>(subPreferences);
}

} // namespace core
} // namespace ledger
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <events/ProgressNotifier.h>
#include <memory>
#include <mutex>
#include <utils/Option.hpp>
#include <wallet/common/synchronizers/SavedStateProvider.hpp>
#include <wallet/pool/WalletPool.hpp>
#include <wallet/ripple/explorers/RippleLikeBlockchainExplorer.h>
#include <wallet/ripple/keychains/RippleLikeKeychain.h>
Expand Down Expand Up @@ -93,6 +95,8 @@ namespace ledger {
class RippleLikeAccountSynchronizer : public DedicatedContext,
public std::enable_shared_from_this<RippleLikeAccountSynchronizer> {
public:
using SavedStateProviderType = SavedStateProvider<AccountSynchronizationSavedState>;

RippleLikeAccountSynchronizer(
const std::shared_ptr<WalletPool> &pool,
const std::shared_ptr<RippleLikeBlockchainExplorer> &explorer);
Expand Down Expand Up @@ -123,12 +127,20 @@ namespace ledger {
std::shared_ptr<SynchronizationBuddy> &buddy,
const std::string &accountUid);

Option<AccountSynchronizationSavedState> getSavedState(const std::shared_ptr<RippleLikeAccount> &account);
void setSavedState(const std::shared_ptr<RippleLikeAccount> &account, AccountSynchronizationSavedState &savedState);

void eraseDataSince(soci::session &sql, const std::chrono::system_clock::time_point &date, const std::shared_ptr<RippleLikeAccount> &account);

private:
std::unique_ptr<RippleLikeAccountSynchronizer::SavedStateProviderType> getSavedStateProvider(const std::shared_ptr<RippleLikeAccount> &account);

std::shared_ptr<RippleLikeBlockchainExplorer> _explorer;
std::shared_ptr<ProgressNotifier<AccountSynchronizationContext>> _notifier;
std::mutex _lock;
std::shared_ptr<RippleLikeAccount> _currentAccount;
std::shared_ptr<Preferences> _internalPreferences;
std::unique_ptr<SavedStateProviderType> _savedStateProvider;
};

} // namespace core
Expand Down