diff --git a/__tests__/unit/core-kernel/utils/transform-plugins.test.ts b/__tests__/unit/core-kernel/utils/transform-plugins.test.ts deleted file mode 100644 index f438f019ac..0000000000 --- a/__tests__/unit/core-kernel/utils/transform-plugins.test.ts +++ /dev/null @@ -1,104 +0,0 @@ -import "jest-extended"; - -import { Plugins } from "@packages/core-kernel/src/utils"; - -describe("transformPlugins", () => { - it("should be ok", () => { - const transformed = Plugins.transformPlugins([ - { - package: "@arkecosystem/core-transactions", - }, - { - package: "@arkecosystem/core-state", - }, - { - package: "@arkecosystem/core-magistrate-transactions", - }, - { - package: "@arkecosystem/core-database", - options: { - connection: { - host: process.env.CORE_DB_HOST || "localhost", - port: process.env.CORE_DB_PORT || 5432, - database: - process.env.CORE_DB_DATABASE || - `${process.env.CORE_TOKEN}_${process.env.CORE_NETWORK_NAME}`, - user: process.env.CORE_DB_USERNAME || process.env.CORE_TOKEN, - password: process.env.CORE_DB_PASSWORD || "password", - }, - }, - }, - { - package: "@arkecosystem/core-transaction-pool", - options: { - enabled: true, - maxTransactionsPerSender: process.env.CORE_TRANSACTION_POOL_MAX_PER_SENDER || 300, - allowedSenders: [], - dynamicFees: { - enabled: true, - minFeePool: 1000, - minFeeBroadcast: 1000, - addonBytes: { - transfer: 100, - secondSignature: 250, - delegateRegistration: 400000, - vote: 100, - multiSignature: 500, - ipfs: 250, - multiPayment: 500, - delegateResignation: 100, - htlcLock: 100, - htlcClaim: 0, - htlcRefund: 0, - }, - }, - }, - }, - { - package: "@arkecosystem/core-p2p", - options: { - server: { - port: process.env.CORE_P2P_PORT || 4000, - }, - minimumNetworkReach: 5, - }, - }, - { - package: "@arkecosystem/core-blockchain", - }, - { - package: "@arkecosystem/core-api", - options: { - enabled: !process.env.CORE_API_DISABLED, - host: process.env.CORE_API_HOST || "0.0.0.0", - port: process.env.CORE_API_PORT || 4003, - }, - }, - { - package: "@arkecosystem/core-webhooks", - options: { - enabled: process.env.CORE_WEBHOOKS_ENABLED, - server: { - host: process.env.CORE_WEBHOOKS_HOST || "0.0.0.0", - port: process.env.CORE_WEBHOOKS_PORT || 4004, - whitelist: ["127.0.0.1", "::ffff:127.0.0.1"], - }, - }, - }, - { - package: "@arkecosystem/core-forger", - }, - ]); - - expect(transformed).toEqual({ - "@arkecosystem/core-api": { - enabled: true, - port: 4003, - }, - "@arkecosystem/core-webhooks": { - enabled: false, - port: 4004, - }, - }); - }); -}); diff --git a/__tests__/unit/core-p2p/socket-server/controllers/peer.test.ts b/__tests__/unit/core-p2p/socket-server/controllers/peer.test.ts index c6b58afee7..c3fbd1b040 100644 --- a/__tests__/unit/core-p2p/socket-server/controllers/peer.test.ts +++ b/__tests__/unit/core-p2p/socket-server/controllers/peer.test.ts @@ -24,15 +24,34 @@ describe("PeerController", () => { getLastDownloadedBlock: jest.fn(), }; const createProcessor = jest.fn(); + const appPlugins = [ { package: "@arkecosystem/core-api", options: {} } ]; + const coreApiServiceProvider = { + name: () => "core-api", + configDefaults: () => ({ + server: { http: { port: 4003 } } + }), + }; + const serviceProviders = { "@arkecosystem/core-api": coreApiServiceProvider, }; + const configRepository = { get: () => appPlugins }; // get("app.plugins") + const serviceProviderRepository = { get: (plugin) => serviceProviders[plugin] }; const appGet = { [Container.Identifiers.BlockchainService]: blockchain, [Container.Identifiers.TransactionPoolProcessorFactory]: createProcessor, + [Container.Identifiers.ConfigRepository]: configRepository, + [Container.Identifiers.ServiceProviderRepository]: serviceProviderRepository, }; const config = { getOptional: jest.fn().mockReturnValue(["127.0.0.1"]) }; // remoteAccess const app = { get: (key) => appGet[key], getTagged: () => config, version: () => "3.0.9", + resolve: () => ({ + from: () => ({ + merge: () => ({ + all: () => ({ server: { http: { port: "4003" } } }) + }) + }) + }) }; beforeAll(() => { diff --git a/__tests__/unit/core-p2p/socket-server/utils/get-peer-config.test.ts b/__tests__/unit/core-p2p/socket-server/utils/get-peer-config.test.ts index fd9d43ce7e..0476dbbcc9 100644 --- a/__tests__/unit/core-p2p/socket-server/utils/get-peer-config.test.ts +++ b/__tests__/unit/core-p2p/socket-server/utils/get-peer-config.test.ts @@ -1,5 +1,6 @@ import { Managers } from "@arkecosystem/crypto"; import { getPeerConfig } from "@arkecosystem/core-p2p/src/socket-server/utils/get-peer-config"; +import { Container } from "@arkecosystem/core-kernel"; describe("getPeerConfig", () => { const mockConfig = { @@ -13,7 +14,56 @@ describe("getPeerConfig", () => { jest.spyOn(Managers.configManager, "get").mockImplementation((key) => mockConfig[key]); const version = "3.0.9"; - const app = { version: () => version }; + const appPlugins = [ + { package: "@arkecosystem/core-api", options: {} }, + { package: "@arkecosystem/core-webhooks" }, + ]; + const coreApiServiceProvider = { + name: () => "core-api", + configDefaults: () => ({ + server: { http: { port: 4003 } } + }), + }; + const coreWebhooksServiceProvider = { + name: () => "core-webhooks", + configDefaults: () => ({}), + }; + const serviceProviders = { + "@arkecosystem/core-api": coreApiServiceProvider, + "@arkecosystem/core-webhooks": coreWebhooksServiceProvider, + } + const configRepository = { get: () => appPlugins }; // get("app.plugins") + const serviceProviderRepository = { get: (plugin) => serviceProviders[plugin] }; + const appGet = { + [Container.Identifiers.ConfigRepository]: configRepository, + [Container.Identifiers.ServiceProviderRepository]: serviceProviderRepository, + } + const app = { + version: () => version, + get: (key) => appGet[key], + resolve: () => ({ + from: () => ({ + merge: () => ({ + all: () => ({ + server: { + http: { + port: "4003" + } + } + }) + }) + }), + discover: () => ({ + merge: () => ({ + all: () => ({ + server: { + port: "4004" + } + }) + }) + }) + }) + }; it("should return own config from config manager", () => { expect(getPeerConfig(app as any)).toEqual({ @@ -28,7 +78,16 @@ describe("getPeerConfig", () => { symbol: mockConfig["network.client.symbol"], }, }, - plugins: {}, + plugins: { + "@arkecosystem/core-api": { + enabled: true, + port: 4003 + }, + "@arkecosystem/core-webhooks": { + enabled: true, + port: 4004 + } + }, }); }); }); diff --git a/packages/core-kernel/src/utils/index.ts b/packages/core-kernel/src/utils/index.ts index 000fdd455f..a64a1debb5 100644 --- a/packages/core-kernel/src/utils/index.ts +++ b/packages/core-kernel/src/utils/index.ts @@ -8,7 +8,6 @@ import { isWhitelisted } from "./is-whitelisted"; import { calculateRound, isNewRound } from "./round-calculator"; export * as Search from "./search"; import { calculate } from "./supply-calculator"; -export * as Plugins from "./transform-plugins"; export * from "@arkecosystem/utils"; export * from "./expiration-calculator"; diff --git a/packages/core-kernel/src/utils/transform-plugins.ts b/packages/core-kernel/src/utils/transform-plugins.ts deleted file mode 100644 index f187afac83..0000000000 --- a/packages/core-kernel/src/utils/transform-plugins.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { PeerPlugins } from "../contracts/p2p"; - -// todo: review the implementation -export const transformPlugins = (plugins): PeerPlugins => { - const result: PeerPlugins = {}; - - const pkgs: { package: string; options: any }[] = Object.values(plugins); - - for (const pkg of pkgs) { - const name = pkg.package; - let options = pkg.options || {}; - - if (options.server) { - options = { - enabled: options.enabled, - ...options.server, - }; - } - - const port = Number(options.port); - const enabled = !!options.enabled; - - if (isNaN(port) || name.includes("core-p2p")) { - continue; - } - - result[name] = { - enabled, - port, - }; - } - - return result; -}; diff --git a/packages/core-p2p/src/socket-server/utils/get-peer-config.ts b/packages/core-p2p/src/socket-server/utils/get-peer-config.ts index 8f01d4f9d7..8a7e79ea34 100644 --- a/packages/core-p2p/src/socket-server/utils/get-peer-config.ts +++ b/packages/core-p2p/src/socket-server/utils/get-peer-config.ts @@ -1,7 +1,70 @@ -// import { Plugins } from "@arkecosystem/core-kernel"; -import { Contracts } from "@arkecosystem/core-kernel"; +import { Contracts, Container, Services, Providers, Utils } from "@arkecosystem/core-kernel"; import { Managers } from "@arkecosystem/crypto"; +type PluginConfig = { package: string; options: any }; + +const transformPlugins = (plugins: PluginConfig[]): Contracts.P2P.PeerPlugins => { + const result: Contracts.P2P.PeerPlugins = {}; + + for (const pluginConfig of plugins) { + const name = pluginConfig.package; + const options = pluginConfig.options?.server?.http + || pluginConfig.options?.server?.https + || pluginConfig.options?.server + || pluginConfig.options + || {}; // lots of options for server configuration... TODO review see if it can be cleaner + + const port = Number(options.port); + + if (isNaN(port) || name.includes("core-p2p")) { + continue; + } + + result[name] = { + enabled: true, // default to true because "enabled" flag is in different place based on which plugin + port, + }; + } + + return result; +}; + +const getPluginsConfig = (plugins: PluginConfig[], app: Contracts.Kernel.Application) => { + return plugins.map(plugin => { + const serviceProvider: Providers.ServiceProvider = app + .get(Container.Identifiers.ServiceProviderRepository) + .get(plugin.package); + + const serviceProviderName: string | undefined = serviceProvider.name(); + + Utils.assert.defined(serviceProviderName); + + const hasDefaults: boolean = Object.keys(serviceProvider.configDefaults()).length > 0; + + if (hasDefaults) { + const pluginConfig = { + package: plugin.package, + options: app + .resolve(Providers.PluginConfiguration) + .from(serviceProviderName, serviceProvider.configDefaults()) + .merge(plugin.options || {}) + .all() + }; + return pluginConfig; + } + + const pluginConfig = { + package: plugin.package, + options: app + .resolve(Providers.PluginConfiguration) + .discover(serviceProviderName) + .merge(plugin.options || {}) + .all() + }; + return pluginConfig; + }); +} + export const getPeerConfig = (app: Contracts.Kernel.Application): Contracts.P2P.PeerConfig => { return { version: app.version(), @@ -15,8 +78,11 @@ export const getPeerConfig = (app: Contracts.Kernel.Application): Contracts.P2P. symbol: Managers.configManager.get("network.client.symbol"), }, }, - plugins: {}, - // todo: review and re-enable - // plugins: Plugins.transformPlugins(appConfig.config.plugins), + plugins: transformPlugins( + getPluginsConfig( + app.get(Container.Identifiers.ConfigRepository).get("app.plugins"), + app + ) + ), }; };