Skip to content

Commit

Permalink
Merge pull request #419 from EdgeApp/sam/info-payload
Browse files Browse the repository at this point in the history
Implement updateInfoPayload
  • Loading branch information
samholmes authored Jan 3, 2025
2 parents a14a7a6 + 5884f0b commit 9ae78a6
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 72 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

- added: Implement `updateInfoPayload` for `EdgeCurrencyEngine` to get currency info updates from info-server.
- fixed: Fixed cleaner failure for getInfo Blockbook request.

## 3.4.5 (2024-12-12)

- added: Edge servers added to blockbook server list for BTC, BCH, DOGE, FIRO, and LTC.
Expand Down
32 changes: 22 additions & 10 deletions src/common/plugin/CurrencyPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { asMaybe } from 'cleaners'
import {
EdgeCorePluginOptions,
EdgeCurrencyEngine,
Expand All @@ -17,7 +18,7 @@ import { makeUtxoEngine } from '../utxobased/engine/UtxoEngine'
import { makeCurrencyTools } from './CurrencyTools'
import { makeEngineEmitter } from './EngineEmitter'
import { makePluginState } from './PluginState'
import { EngineConfig, PluginInfo } from './types'
import { asInfoPayload, EngineConfig, PluginInfo } from './types'

let hasMemletBeenSet = false

Expand All @@ -29,13 +30,15 @@ export function makeCurrencyPlugin(
const { initOptions, io, log, nativeIo, pluginDisklet } = pluginOptions
const currencyTools = makeCurrencyTools(io, pluginInfo)
const { defaultSettings, pluginId, currencyCode } = currencyInfo

const pluginState = makePluginState({
io,
defaultSettings: asUtxoUserSettings(defaultSettings),
currencyCode,
pluginId,
pluginDisklet,
infoPayload: asMaybe(asInfoPayload)(pluginOptions.infoPayload),
io,
log,
defaultSettings: asUtxoUserSettings(defaultSettings)
pluginId,
pluginDisklet
})

if (!hasMemletBeenSet) {
Expand All @@ -49,7 +52,7 @@ export function makeCurrencyPlugin(
}
}

return {
const instance: EdgeCurrencyPlugin = {
currencyInfo,

async makeCurrencyEngine(
Expand All @@ -64,10 +67,9 @@ export function makeCurrencyPlugin(
currencyTools,
initOptions: asUtxoInitOptions(initOptions),
io,
options: {
...pluginOptions,
...engineOptions,
emitter
emitter,
engineOptions: {
...engineOptions
},
pluginState
}
Expand All @@ -81,6 +83,16 @@ export function makeCurrencyPlugin(
throw e
})
return currencyTools
},

async updateInfoPayload(infoPayload) {
try {
pluginState.infoPayload = asInfoPayload(infoPayload)
} catch (_) {
log.warn('invalid infoPayload', infoPayload)
}
}
}

return instance
}
63 changes: 23 additions & 40 deletions src/common/plugin/PluginState.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Typescript translation from original code in edge-currency-bitcoin

import { asArray, asEither, asNull, asObject, asString } from 'cleaners'
import { Disklet } from 'disklet'
import { EdgeIo, EdgeLog } from 'edge-core-js/types'
import { makeMemlet } from 'memlet'
Expand All @@ -13,16 +10,12 @@ import {
ServerList,
ServerScores
} from './ServerScores'
import { InfoPayload } from './types'

// Info server endpoint to getting ServerListInfo data
const serverListInfoUrl = 'https://info1.edge.app/v1/blockbook/'
// The filename for ServerInfoCache data (see ServerScores.ts)
// Perhaps this should be in ServerScores.ts file, but that'll take some refactoring
const SERVER_CACHE_FILE = 'serverCache.json'

// ServerListInfo data structure from info server and saved to disk
const asServerListInfo = asObject(asEither(asArray(asString), asNull))

/** A JSON object (as opposed to an array or primitive). */
interface JsonObject {
[name: string]: unknown
Expand All @@ -33,15 +26,18 @@ interface JsonObject {
* Engine plugins are responsible for keeping it up to date.
*/
export interface PluginStateSettings {
io: EdgeIo
defaultSettings: UtxoUserSettings
currencyCode: string
pluginId: string
pluginDisklet: Disklet
defaultSettings: UtxoUserSettings
infoPayload: InfoPayload | undefined
io: EdgeIo
log: EdgeLog
pluginDisklet: Disklet
pluginId: string
}

export interface PluginState {
infoPayload: InfoPayload | undefined

addEngine: (engineProcessor: UtxoEngineProcessor) => void
removeEngine: (engineProcessor: UtxoEngineProcessor) => void
dumpData: () => JsonObject
Expand All @@ -58,14 +54,7 @@ export interface PluginState {
}

export function makePluginState(settings: PluginStateSettings): PluginState {
const {
io,
defaultSettings,
currencyCode,
pluginId,
pluginDisklet,
log
} = settings
const { defaultSettings, log, pluginDisklet, pluginId } = settings

let engines: UtxoEngineProcessor[] = []
const memlet = makeMemlet(pluginDisklet)
Expand Down Expand Up @@ -118,27 +107,21 @@ export function makePluginState(settings: PluginStateSettings): PluginState {
onDirtyServer
})

const fetchServers = async (): Promise<string[]> => {
log(`${pluginId} - GET ${serverListInfoUrl}`)

try {
const response = await io.fetch(serverListInfoUrl)
if (!response.ok) {
throw new Error(`Failed with status ${response.status}`)
}
const responseBody = await response.json()
const serverListInfo = asServerListInfo(responseBody)

return serverListInfo[currencyCode] ?? []
} catch (error) {
log.warn(
`${pluginId} - GET ${serverListInfoUrl} failed: ${error.toString()}`
)
const getInfoPayloadServers = async (): Promise<string[]> => {
if (instance.infoPayload == null) {
log.warn(`info server list list empty`)
return []
}

const servers = Object.keys(instance.infoPayload.blockbookServers)
log.warn(`info server list`, servers)

return servers
}

const instance: PluginState = {
infoPayload: settings.infoPayload,

/**
* Begins notifying the engine of state changes. Used at connection time.
*/
Expand Down Expand Up @@ -210,11 +193,11 @@ export function makePluginState(settings: PluginStateSettings): PluginState {
// Use the default servers from info file as final fallback
defaultSettings.blockbookServers
} else {
const fetchedServers = await fetchServers()
const infoPayloadServers = await getInfoPayloadServers()
newServers =
fetchedServers.length > 0
? // Use the servers from the network query
fetchedServers
infoPayloadServers.length > 0
? // Use the servers from the info-server
infoPayloadServers
: // Use the default servers from info file as final fallback
defaultSettings.blockbookServers
}
Expand Down
12 changes: 7 additions & 5 deletions src/common/plugin/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,20 +356,22 @@ export interface EngineConfig {
pluginInfo: PluginInfo
pluginDisklet: Disklet
currencyTools: EdgeCurrencyTools
options: EngineOptions
engineOptions: EdgeCurrencyEngineOptions
emitter: EngineEmitter
initOptions: UtxoInitOptions
io: EdgeIo
pluginState: PluginState
}

export interface EngineOptions extends EdgeCurrencyEngineOptions {
emitter: EngineEmitter
}

export type LocalWalletMetadata = ReturnType<typeof asLocalWalletMetadata>
export const asLocalWalletMetadata = asObject({
balance: asString,
// scriptPubkey -> balance
addressBalances: asObject(asString),
lastSeenBlockHeight: asNumber
})

export const asInfoPayload = asObject({
blockbookServers: asObject(asBoolean)
})
export type InfoPayload = ReturnType<typeof asInfoPayload>
23 changes: 9 additions & 14 deletions src/common/utxobased/engine/UtxoEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,14 @@ export async function makeUtxoEngine(
const {
pluginInfo,
pluginDisklet,
// Rename to make it explicit that this is sensitive memory
options,
emitter,
engineOptions,
io,
pluginState
} = config
const {
walletLocalDisklet,
walletLocalEncryptedDisklet,
emitter,
log
} = options
const { walletLocalDisklet, walletLocalEncryptedDisklet, log } = engineOptions
const { currencyInfo, engineInfo, coinInfo } = pluginInfo
const userSettings = asUtxoUserSettings(options.userSettings)
const userSettings = asUtxoUserSettings(engineOptions.userSettings)

// We should move the active server list to the engine state,
// since multiple accounts can be logged in at once,
Expand Down Expand Up @@ -120,7 +115,7 @@ export async function makeUtxoEngine(
disklet: pluginDisklet,
pluginInfo,
io,
log: config.options.log
log: config.engineOptions.log
})

const metadata = await makeMetadata({
Expand Down Expand Up @@ -983,11 +978,11 @@ export async function makeUtxoEngine(

const tmpEngineProcessor = makeUtxoEngineProcessor({
...config,
options: {
...config.options,
emitter: tmpEmitter,
engineOptions: {
...config.engineOptions,
walletLocalDisklet: tmpDisklet,
walletLocalEncryptedDisklet: tmpEncryptedDisklet,
emitter: tmpEmitter
walletLocalEncryptedDisklet: tmpEncryptedDisklet
},
pluginInfo: {
...pluginInfo,
Expand Down
5 changes: 3 additions & 2 deletions src/common/utxobased/engine/UtxoEngineProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,15 @@ export function makeUtxoEngineProcessor(
const {
initOptions,
io,
options,
emitter,
engineOptions,
pluginState,
pluginInfo,
dataLayer,
walletInfo,
walletTools
} = config
const { emitter, log } = options
const { log } = engineOptions

const { walletFormats } = walletInfo.keys

Expand Down
2 changes: 1 addition & 1 deletion src/common/utxobased/network/blockbookApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export const asInfoResponse = asObject({
bestHash: asString,
block0Hash: asString,
testnet: asBoolean,
backend: asOptional(
backend: asMaybe(
asObject({
version: asString,
subversion: asString
Expand Down

0 comments on commit 9ae78a6

Please sign in to comment.