Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch plugin data from info server #587

Merged
merged 7 commits into from
Mar 23, 2024
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
2 changes: 0 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@
],
"rules": {
"@typescript-eslint/default-param-last": "off",
"@typescript-eslint/no-dynamic-delete": "off",
"@typescript-eslint/no-invalid-void-type": "off",
"@typescript-eslint/promise-function-async": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"simple-import-sort/imports": "error"
}
}
4 changes: 2 additions & 2 deletions src/core/account/account-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,8 +621,8 @@ export function makeAccountApi(ai: ApiInput, accountId: string): EdgeAccount {
throw new Error(
`activateWallet unsupported by walletId ${activateWalletId}`
)
const walletId = paymentInfo?.walletId
const wallet = currencyWallets[walletId ?? '']
const walletId = paymentInfo?.walletId ?? ''
const wallet = currencyWallets[walletId]

if (wallet == null) {
throw new Error(`No wallet for walletId ${walletId}`)
Expand Down
5 changes: 1 addition & 4 deletions src/core/account/account-pixie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,7 @@ const accountPixie: TamePixie<AccountProps> = combinePixies({

return {
update() {
const { accountOutput } = input.props
if (accountOutput == null) return
const { accountApi } = accountOutput
if (accountApi == null) return
if (input.props.accountOutput?.accountApi == null) return

// Start once the EdgeAccount API exists:
dataTask.start({ wait: true })
Expand Down
4 changes: 1 addition & 3 deletions src/core/account/lobby-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ export async function fetchAppIdInfo(
appId: string
): Promise<AppIdInfo> {
try {
const infoServerUri = shuffle(
ai.props.state.contextConfig.edgeServers.infoServers
)[0]
const [infoServerUri] = shuffle(ai.props.state.infoServers)
const url = `${infoServerUri}/v1/appIdInfo/${appId}`
const response = await ai.props.io.fetch(url)
if (response.status === 404) {
Expand Down
6 changes: 6 additions & 0 deletions src/core/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
EdgeWalletStates
} from '../types/types'
import { SwapSettings } from './account/account-types'
import { InfoCacheFile } from './context/info-cache-file'
import {
MergedTransaction,
TxFileJsons,
Expand Down Expand Up @@ -326,13 +327,18 @@ export type RootAction =
walletInfo: EdgeWalletInfo
}
}
| {
type: 'INFO_CACHE_FETCHED'
payload: InfoCacheFile
}
| {
// Initializes the redux store on context creation.
type: 'INIT'
payload: {
apiKey: string
appId: string
authServer: string
infoCache: InfoCacheFile
infoServers: string[]
syncServers: string[]
clientId: Uint8Array
Expand Down
49 changes: 47 additions & 2 deletions src/core/context/context-pixie.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import { combinePixies, stopUpdates, TamePixie } from 'redux-pixies'
import {
combinePixies,
filterPixie,
stopUpdates,
TamePixie
} from 'redux-pixies'
import { close, update } from 'yaob'

import { EdgeContext, EdgeLogSettings, EdgeUserInfo } from '../../types/types'
import { makePeriodicTask } from '../../util/periodic-task'
import { shuffle } from '../../util/shuffle'
import { ApiInput, RootProps } from '../root-pixie'
import { makeContextApi } from './context-api'
import {
asInfoCacheFile,
INFO_CACHE_FILE_NAME,
infoCacheFile
} from './info-cache-file'

export interface ContextOutput {
api: EdgeContext
Expand Down Expand Up @@ -41,5 +53,38 @@ export const context: TamePixie<RootProps> = combinePixies({
}
}
}
}
},

infoFetcher: filterPixie(
(input: ApiInput) => {
async function doInfoSync(): Promise<void> {
const { dispatch, io } = input.props

const [infoServerUri] = shuffle(input.props.state.infoServers)
const response = await fetch(`${infoServerUri}/v1/coreRollup`, {
headers: { accept: 'application/json' }
})
if (!response.ok) return
const json = await response.json()

const infoCache = asInfoCacheFile(json)
dispatch({
type: 'INFO_CACHE_FETCHED',
payload: infoCache
})
await infoCacheFile.save(io.disklet, INFO_CACHE_FILE_NAME, infoCache)
}

const infoTask = makePeriodicTask(doInfoSync, 10 * 60 * 1000)
infoTask.start()

return {
update() {},
destroy() {
infoTask.stop()
}
}
},
props => (props.state.paused ? undefined : props)
)
})
31 changes: 0 additions & 31 deletions src/core/context/context-reducer.ts

This file was deleted.

18 changes: 18 additions & 0 deletions src/core/context/info-cache-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { asArray, asObject, asString } from 'cleaners'

import { EdgePluginMap, JsonObject } from '../../browser'
import { asJsonObject, makeJsonFile } from '../../util/file-helpers'

export interface InfoCacheFile {
corePlugins?: EdgePluginMap<JsonObject>
syncServers?: string[]
}

export const INFO_CACHE_FILE_NAME = 'infoCache.json'

export const asInfoCacheFile = asObject<InfoCacheFile>({
corePlugins: asObject(asJsonObject),
syncServers: asArray(asString)
})

export const infoCacheFile = makeJsonFile(asInfoCacheFile)
34 changes: 32 additions & 2 deletions src/core/currency/currency-pixie.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { combinePixies, mapPixie, TamePixie } from 'redux-pixies'

import { RootProps } from '../root-pixie'
import { matchJson } from '../../util/match-json'
import { InfoCacheFile } from '../context/info-cache-file'
import { ApiInput, RootProps } from '../root-pixie'
import {
CurrencyWalletOutput,
CurrencyWalletProps,
Expand All @@ -21,5 +23,33 @@ export const currency: TamePixie<RootProps> = combinePixies({
walletState: props.state.currency.wallets[walletId],
walletOutput: props.output.currency.wallets[walletId]
})
)
),

pluginUpdater(input: ApiInput) {
samholmes marked this conversation as resolved.
Show resolved Hide resolved
let lastInfo: InfoCacheFile | undefined

return async () => {
const { infoCache, plugins } = input.props.state

// Bail out quickly if nothing has changed:
if (lastInfo === infoCache) return

// Update plugins after the first run:
if (lastInfo != null) {
for (const pluginId of Object.keys(plugins.currency)) {
const plugin = plugins.currency[pluginId]
const newPayload = infoCache.corePlugins?.[pluginId] ?? {}
const oldPayload = lastInfo.corePlugins?.[pluginId] ?? {}

if (
plugin.updateInfoPayload != null &&
!matchJson(oldPayload, newPayload)
) {
await plugin.updateInfoPayload(newPayload)
}
}
}
lastInfo = infoCache
}
}
})
10 changes: 3 additions & 7 deletions src/core/currency/wallet/currency-wallet-callbacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,7 @@ import {
CurrencyWalletInput,
CurrencyWalletProps
} from './currency-wallet-pixie'
import {
MergedTransaction,
mergeTx,
TxidHashes
} from './currency-wallet-reducer'
import { mergeTx, TxidHashes } from './currency-wallet-reducer'
import { uniqueStrings } from './enabled-tokens'

let throttleRateLimitMs = 5000
Expand Down Expand Up @@ -198,7 +194,7 @@ export function makeCurrencyWalletCallbacks(
return
}
pushUpdate({
id: `${walletId}==${tokenId}`,
id: `${walletId}==${String(tokenId)}`,
action: 'onTokenBalanceChanged',
updateFunc: () => {
input.props.dispatch({
Expand Down Expand Up @@ -418,7 +414,7 @@ export function watchCurrencyWallet(input: CurrencyWalletInput): void {
}

export const validateConfirmations = (
tx: EdgeTransaction | MergedTransaction,
tx: { blockHeight: number }, // Either EdgeTransaction or MergedTransaction
blockHeight: number,
requiredConfirmations: number = 1 // Default confirmation rule is 1 block
): EdgeTransaction['confirmations'] => {
Expand Down
3 changes: 2 additions & 1 deletion src/core/currency/wallet/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export const asEdgeMetadata: Cleaner<EdgeMetadata> = raw => {
const { exchangeAmount = {} } = clean

// Delete corrupt amounts that exceed the Javascript number range:
for (const fiat of Object.keys(clean)) {
for (const fiat of Object.keys(exchangeAmount)) {
if (String(exchangeAmount[fiat]).includes('e')) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete exchangeAmount[fiat]
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/core/fake/fake-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ export type DbLogin = Omit<EdgeLoginDump, 'children'>
* Emulates the Airbitz login server database.
*/
export class FakeDb {
lobbies: { [lobbyId: string]: DbLobby }
lobbies: Map<string, DbLobby>
logins: DbLogin[]
repos: { [syncKey: string]: EdgeRepoDump }
repos: Map<string, EdgeRepoDump>

constructor() {
this.lobbies = {}
this.lobbies = new Map()
this.logins = []
this.repos = {}
this.repos = new Map()
}

getLoginById(loginId: Uint8Array): DbLogin | undefined {
Expand Down Expand Up @@ -80,7 +80,7 @@ export class FakeDb {
}

setupRepo(syncKey: string, repo: EdgeRepoDump): void {
this.repos[syncKey] = repo
this.repos.set(syncKey, repo)
}

dumpLogin(login: DbLogin): EdgeLoginDump {
Expand Down
12 changes: 6 additions & 6 deletions src/core/fake/fake-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ function createLogin(request: ApiRequest, login?: DbLogin): HttpResponse {
keyBoxes: []
}))(body.data)
for (const syncKey of keys.newSyncKeys) {
db.repos[syncKey] = {}
db.repos.set(syncKey, {})
}

// Start building the new database row:
Expand Down Expand Up @@ -326,7 +326,7 @@ const addKeysRoute = withLogin2(request => {

// Set up repos:
for (const syncKey of clean.newSyncKeys) {
db.repos[syncKey] = {}
db.repos.set(syncKey, {})
}
login.keyBoxes = softCat(login.keyBoxes, clean.keyBoxes)

Expand Down Expand Up @@ -596,7 +596,7 @@ const withLobby =
request => {
const { db, path } = request
const lobbyId = path.split('/')[4]
const lobby = db.lobbies[lobbyId]
const lobby = db.lobbies.get(lobbyId)
return lobby != null
? server({ ...request, lobby, lobbyId })
: fallback({ ...request, lobbyId })
Expand All @@ -619,7 +619,7 @@ const createLobbyRoute = withLobby(
const { timeout = 600 } = clean
const expires = new Date(Date.now() + 1000 * timeout).toISOString()

db.lobbies[lobbyId] = { request: clean, replies: [], expires }
db.lobbies.set(lobbyId, { request: clean, replies: [], expires })
return statusResponse()
}
)
Expand All @@ -643,7 +643,7 @@ const getLobbyRoute = withLobby(request => {

const deleteLobbyRoute = withLobby(request => {
const { db, lobbyId } = request
delete db.lobbies[lobbyId]
db.lobbies.delete(lobbyId)
return statusResponse()
})

Expand Down Expand Up @@ -682,7 +682,7 @@ const withRepo =
const syncKey = elements[4]
// const hash = elements[5]

const repo = db.repos[syncKey]
const repo = db.repos.get(syncKey)
if (repo == null) {
// This is not the auth server, so we have a different format:
return jsonResponse({ msg: 'Hash not found' }, { status: 404 })
Expand Down
7 changes: 5 additions & 2 deletions src/core/fake/fake-world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ export function makeFakeWorld(

// Find the data on the server:
const login = fakeDb.getLoginById(loginId)
if (login == null) throw new Error(`Cannot find user ${account.username}`)
if (login == null) {
throw new Error(`Cannot find user ${account.rootLoginId}`)
}

// Figure out which repos to use:
const syncKeys: string[] = []
Expand All @@ -171,7 +173,8 @@ export function makeFakeWorld(
}
const repos: EdgeFakeUser['repos'] = {}
for (const syncKey of syncKeys) {
repos[syncKey] = wasEdgeRepoDump(fakeDb.repos[syncKey])
const repo = fakeDb.repos.get(syncKey)
if (repo != null) repos[syncKey] = wasEdgeRepoDump(repo)
}

return {
Expand Down
Loading
Loading