Skip to content

Commit

Permalink
Bug fix and improvement on marina events (#378)
Browse files Browse the repository at this point in the history
* adds accountID to console.debug

* Bug fixes:

- fix bug where only the main account was emitting events on NEW_TX, NEW_UTXO and SPENT_UTXO

Breaking changes (marina events):

- marina.on('NEW_TX', (tx) => {}) is now marina.on('NEW_TX', ({ tx, accountID }) => {})
- marina.on('NEW_UTXO', (utxo) => {}) is now marina.on('NEW_UTXO', ({ utxo, accountID }) => {})
- marina.on('SPENT_UTXO', (utxo) => {}) is now marina.on('SPENT_UTXO', ({ utxo, accountID }) => {})

* prettier

* make all events return the same MarinaEvent type
  • Loading branch information
bordalix authored Aug 18, 2022
1 parent 3fb3322 commit a60d912
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 30 deletions.
3 changes: 1 addition & 2 deletions src/application/redux/sagas/updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ function* utxosUpdater(
if (Object.keys(receivedUtxos).length > 0) {
yield put(unlockUtxos());
}

console.debug(`${new Date()} utxos received`, receivedUtxos);
console.debug(`${new Date()} utxos received for ${accountID}`, receivedUtxos);
}

const putAddTxAction = (accountID: AccountID, network: NetworkString, walletScripts: string[]) =>
Expand Down
38 changes: 22 additions & 16 deletions src/application/utils/marina-event.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { NetworkString, Outpoint, UnblindedOutput } from 'ldk';
import type { NetworkString, UnblindedOutput } from 'ldk';
import type { TxDisplayInterface, TxsHistory } from '../../domain/transaction';
import type { MarinaEventType } from 'marina-provider';

Expand All @@ -7,25 +7,30 @@ export interface MarinaEvent<P extends any> {
payload: P;
}

export type NewUtxoMarinaEvent = MarinaEvent<UnblindedOutput>;
export type SpentUtxoMarinaEvent = MarinaEvent<Outpoint>;
export type NewTxMarinaEvent = MarinaEvent<TxDisplayInterface>;
export type EnabledMarinaEvent = MarinaEvent<{ network: NetworkString; hostname: string }>;
export type DisabledMarinaEvent = MarinaEvent<{ network: NetworkString; hostname: string }>;
export type NetworkMarinaEvent = MarinaEvent<NetworkString>;
export type NewUtxoMarinaEvent = MarinaEvent<{ accountID: string; data: UnblindedOutput }>;
export type SpentUtxoMarinaEvent = MarinaEvent<{ accountID: string; data: UnblindedOutput }>;
export type NewTxMarinaEvent = MarinaEvent<{ accountID: string; data: TxDisplayInterface }>;
export type EnabledMarinaEvent = MarinaEvent<{
data: { hostname: string; network: NetworkString };
}>;
export type DisabledMarinaEvent = MarinaEvent<{
data: { hostname: string; network: NetworkString };
}>;
export type NetworkMarinaEvent = MarinaEvent<{ data: NetworkString }>;

// compare tx history states and return marina events
export function compareTxsHistoryState(
oldState: TxsHistory,
newState: TxsHistory
newState: TxsHistory,
accountID: string
): NewTxMarinaEvent[] {
const events: NewTxMarinaEvent[] = [];
const newEntries = Object.entries(newState);
const oldTxIDs = Object.keys(oldState);

for (const [txID, tx] of newEntries) {
if (oldTxIDs.includes(txID)) continue;
events.push({ type: 'NEW_TX', payload: tx });
events.push({ type: 'NEW_TX', payload: { accountID, data: tx } });
}

return events;
Expand All @@ -34,7 +39,8 @@ export function compareTxsHistoryState(
// compare two utxo state and return marina events
export function compareUtxoState(
oldState: Record<string, UnblindedOutput>,
newState: Record<string, UnblindedOutput>
newState: Record<string, UnblindedOutput>,
accountID: string
): (NewUtxoMarinaEvent | SpentUtxoMarinaEvent)[] {
const events: (NewUtxoMarinaEvent | SpentUtxoMarinaEvent)[] = [];
const newEntries = Object.entries(newState);
Expand All @@ -43,15 +49,15 @@ export function compareUtxoState(
for (const [outpointStr, utxo] of newEntries) {
const oldStateHasUtxo = oldOutpointStrings.includes(outpointStr);
if (!oldStateHasUtxo) {
events.push({ type: 'NEW_UTXO', payload: utxo });
events.push({ type: 'NEW_UTXO', payload: { accountID, data: utxo } });
}
}

const newOutpointStrings = Object.keys(newState);

for (const [outpointStr, utxo] of Object.entries(oldState)) {
if (!newOutpointStrings.includes(outpointStr)) {
events.push({ type: 'SPENT_UTXO', payload: utxo });
events.push({ type: 'SPENT_UTXO', payload: { accountID, data: utxo } });
}
}

Expand All @@ -71,24 +77,24 @@ export function compareEnabledWebsites(

for (const hostname of newHostnames) {
if (!oldHostnames.includes(hostname)) {
events.push({ type: 'ENABLED', payload: { network, hostname } });
events.push({ type: 'ENABLED', payload: { data: { hostname, network } } });
}
}

for (const hostname of oldHostnames) {
if (!newHostnames.includes(hostname)) {
events.push({ type: 'DISABLED', payload: { network, hostname } });
events.push({ type: 'DISABLED', payload: { data: { hostname, network } } });
}
}
}

return events.filter((ev) => ev.payload.hostname === currentHostname);
return events.filter((ev) => ev.payload.data.hostname === currentHostname);
}

export function networkChange(
oldNetwork: NetworkString,
newNetwork: NetworkString
): NetworkMarinaEvent[] {
if (oldNetwork !== newNetwork) return [{ type: 'NETWORK', payload: newNetwork }];
if (oldNetwork !== newNetwork) return [{ type: 'NETWORK', payload: { data: newNetwork } }];
else return [];
}
5 changes: 3 additions & 2 deletions src/content/marina/marinaBroker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ export default class MarinaBroker extends Broker<keyof Marina> {
this.store.subscribe(() => {
if (!this.store) throw MarinaBroker.NotSetUpError;
const state = this.store.getState();
const newCache = newCacheFromState(state);
const events = compareCacheForEvents(newCache, this.cache, this.hostname);
const allAccountsIDs = selectAllAccountsIDs(state);
const newCache = newCacheFromState(state, allAccountsIDs);
const events = compareCacheForEvents(newCache, this.cache, this.hostname, allAccountsIDs);

this.cache = newCache; // update the cache state

Expand Down
52 changes: 42 additions & 10 deletions src/content/store-cache.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import type { NetworkString, UnblindedOutput } from 'ldk';
import type { MarinaEvent } from '../application/utils/marina-event';
import type {
MarinaEvent,
NewTxMarinaEvent,
NewUtxoMarinaEvent,
SpentUtxoMarinaEvent,
} from '../application/utils/marina-event';
import {
compareEnabledWebsites,
compareTxsHistoryState,
Expand All @@ -10,17 +15,25 @@ import { MainAccountID } from '../domain/account';
import type { RootReducerState } from '../domain/common';
import type { TxsHistory } from '../domain/transaction';

export interface StoreCache {
export interface StoreCacheAccount {
utxoState: Record<string, UnblindedOutput>;
txsHistoryState: TxsHistory;
}

export interface StoreCache {
accounts: Record<string, StoreCacheAccount>;
enabledWebsitesState: Record<NetworkString, string[]>;
network: NetworkString;
}

export function newStoreCache(): StoreCache {
return {
const accounts: Record<string, StoreCacheAccount> = {};
accounts[MainAccountID] = {
utxoState: {},
txsHistoryState: {},
};
return {
accounts,
enabledWebsitesState: { regtest: [], liquid: [], testnet: [] },
network: 'liquid',
};
Expand All @@ -31,10 +44,23 @@ export function newStoreCache(): StoreCache {
export function compareCacheForEvents(
newCache: StoreCache,
oldCache: StoreCache,
hostname: string // for ENABLED and DISABLED events
hostname: string, // for ENABLED and DISABLED events
allAccountsIDs: string[] // for UTXO and TX events
): MarinaEvent<any>[] {
const utxosEvents = compareUtxoState(oldCache.utxoState, newCache.utxoState);
const txsEvents = compareTxsHistoryState(oldCache.txsHistoryState, newCache.txsHistoryState);
const txsEvents: NewTxMarinaEvent[] = [];
const utxosEvents: (NewUtxoMarinaEvent | SpentUtxoMarinaEvent)[] = [];
for (const accountID of allAccountsIDs) {
compareUtxoState(
oldCache.accounts[accountID]?.utxoState || {},
newCache.accounts[accountID]?.utxoState || {},
accountID
).map((ev) => utxosEvents.push(ev));
compareTxsHistoryState(
oldCache.accounts[accountID]?.txsHistoryState || {},
newCache.accounts[accountID]?.txsHistoryState || {},
accountID
).map((ev) => txsEvents.push(ev));
}
const enabledAndDisabledEvents = compareEnabledWebsites(
oldCache.enabledWebsitesState,
newCache.enabledWebsitesState,
Expand All @@ -46,11 +72,17 @@ export function compareCacheForEvents(
}

// create cache from State.
export function newCacheFromState(state: RootReducerState): StoreCache {
export function newCacheFromState(state: RootReducerState, allAccountsIDs: string[]): StoreCache {
const accounts: Record<string, StoreCacheAccount> = {};
for (const accountID of allAccountsIDs) {
const root = state.wallet.unspentsAndTransactions[accountID][state.app.network];
accounts[accountID] = {
utxoState: root.utxosMap,
txsHistoryState: root.transactions,
};
}
return {
utxoState: state.wallet.unspentsAndTransactions[MainAccountID][state.app.network].utxosMap,
txsHistoryState:
state.wallet.unspentsAndTransactions[MainAccountID][state.app.network].transactions,
accounts,
enabledWebsitesState: state.connect.enabledSites,
network: state.app.network,
};
Expand Down

0 comments on commit a60d912

Please sign in to comment.