Skip to content

Commit

Permalink
Merge pull request #587 from EdgeApp/william/info-fetch
Browse files Browse the repository at this point in the history
Fetch plugin data from info server
  • Loading branch information
swansontec authored Mar 23, 2024
2 parents 37cc5f4 + c2301f6 commit eb1f9f7
Show file tree
Hide file tree
Showing 24 changed files with 252 additions and 99 deletions.
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) {
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

0 comments on commit eb1f9f7

Please sign in to comment.