11import { OceanP2P } from './components/P2P/index.js'
22import { OceanProvider } from './components/Provider/index.js'
33import { OceanIndexer } from './components/Indexer/index.js'
4- import { OceanNodeConfig , P2PCommandResponse } from './@types/OceanNode.js'
4+ import {
5+ AccessListContract ,
6+ OceanNodeConfig ,
7+ P2PCommandResponse
8+ } from './@types/OceanNode.js'
9+ import { ValidateChainId } from './@types/commands.js'
10+
511import { Database } from './components/database/index.js'
612import { Escrow } from './components/core/utils/escrow.js'
713import { CoreHandlersRegistry } from './components/core/handler/coreHandlersRegistry.js'
@@ -15,6 +21,8 @@ import { BlockchainRegistry } from './components/BlockchainRegistry/index.js'
1521import { Blockchain } from './utils/blockchain.js'
1622import { createPersistentStorage } from './components/persistentStorage/createPersistentStorage.js'
1723import { PersistentStorageFactory } from './components/persistentStorage/PersistentStorageFactory.js'
24+ import { isAddress , FallbackProvider , ethers } from 'ethers'
25+ import { create256Hash } from './utils/crypt.js'
1826
1927export interface RequestLimiter {
2028 requester : string | string [ ] // IP address or peer ID
@@ -40,6 +48,7 @@ export class OceanNode {
4048 private requestMap : Map < string , RequestLimiter >
4149 private auth : Auth
4250 private persistentStorage : PersistentStorageFactory
51+ private database : Database
4352
4453 // eslint-disable-next-line no-useless-constructor
4554 private constructor (
@@ -51,21 +60,15 @@ export class OceanNode {
5160 public keyManager ?: KeyManager ,
5261 public blockchainRegistry ?: BlockchainRegistry
5362 ) {
54- if ( keyManager ) {
55- this . keyManager = keyManager
56- } else {
57- this . keyManager = new KeyManager ( config )
58- }
59- if ( blockchainRegistry ) {
60- this . blockchainRegistry = blockchainRegistry
61- } else {
62- this . blockchainRegistry = new BlockchainRegistry ( this . keyManager , config )
63- }
64- this . coreHandlers = CoreHandlersRegistry . getInstance ( this )
63+ this . keyManager = keyManager
64+ this . blockchainRegistry = blockchainRegistry
65+ this . coreHandlers = CoreHandlersRegistry . getInstance ( this , true )
6566 this . requestMap = new Map < string , RequestLimiter > ( )
6667 this . config = config
68+ this . database = db
69+
6770 if ( this . db && this . db ?. authToken ) {
68- this . auth = new Auth ( this . db . authToken )
71+ this . auth = new Auth ( this . db . authToken , config )
6972 }
7073 if ( node ) {
7174 node . setCoreHandlers ( this . coreHandlers )
@@ -86,6 +89,7 @@ export class OceanNode {
8689 this . persistentStorage = null
8790 }
8891 }
92+ this . addIndexer ( indexer )
8993 }
9094
9195 // Singleton instance
@@ -104,10 +108,19 @@ export class OceanNode {
104108 if ( ! config ) {
105109 throw new Error ( 'KeyManager and BlockchainRegistry are required' )
106110 }
107- keyManager = new KeyManager ( config )
108- blockchainRegistry = new BlockchainRegistry ( keyManager , config )
111+ if ( ! keyManager ) keyManager = new KeyManager ( config )
112+ if ( ! blockchainRegistry )
113+ blockchainRegistry = new BlockchainRegistry ( keyManager , config )
109114 }
110- // prepare compute engines
115+ // teardown old instance if needed
116+ this . instance ?. tearDownAll ( ) . catch ( ( err : unknown ) => {
117+ OCEAN_NODE_LOGGER . warn (
118+ `Failed to tear down previous OceanNode instance: ${
119+ err instanceof Error ? err . message : String ( err )
120+ } `
121+ )
122+ } )
123+ OCEAN_NODE_LOGGER . debug ( 'Creating new OceanNode instance' )
111124 this . instance = new OceanNode (
112125 config ,
113126 db ,
@@ -117,6 +130,8 @@ export class OceanNode {
117130 keyManager ,
118131 blockchainRegistry
119132 )
133+ } else {
134+ OCEAN_NODE_LOGGER . debug ( 'Return cached OceanNode instance' )
120135 }
121136 return this . instance
122137 }
@@ -127,7 +142,34 @@ export class OceanNode {
127142 }
128143
129144 public addIndexer ( _indexer : OceanIndexer ) {
145+ const previous = this . indexer
130146 this . indexer = _indexer
147+ if ( previous ) {
148+ previous . stop ( ) . catch ( ( err : unknown ) => {
149+ OCEAN_NODE_LOGGER . warn (
150+ `Failed to stop replaced indexer: ${ err instanceof Error ? err . message : String ( err ) } `
151+ )
152+ } )
153+ }
154+ }
155+
156+ public async tearDownAll ( ) {
157+ if ( this . c2dEngines ) {
158+ await this . c2dEngines . stopAllEngines ( )
159+ this . c2dEngines = null
160+ }
161+ if ( this . indexer ) {
162+ await this . indexer . stop ( )
163+ this . indexer = null
164+ }
165+ if ( this . blockchainRegistry ) {
166+ this . blockchainRegistry . stop ( )
167+ this . blockchainRegistry = null
168+ }
169+ if ( OceanNode . instance === this ) {
170+ OceanNode . instance = null
171+ }
172+ OCEAN_NODE_LOGGER . debug ( 'OceanNode instance stopped & cleared' )
131173 }
132174
133175 public async addC2DEngines ( ) {
@@ -161,11 +203,7 @@ export class OceanNode {
161203 return this . indexer
162204 }
163205
164- public getDatabase ( ) : Database {
165- return this . db
166- }
167-
168- public getC2DEngines ( ) : C2DEngines {
206+ public getC2DEngines ( ) : C2DEngines | undefined {
169207 return this . c2dEngines
170208 }
171209
@@ -259,4 +297,88 @@ export class OceanNode {
259297 }
260298 }
261299 }
300+
301+ getAdminAddresses ( ) : { addresses : string [ ] ; accessLists : any } {
302+ const ret = {
303+ addresses : [ ] as string [ ] ,
304+ accessLists : undefined as AccessListContract | undefined
305+ }
306+
307+ if ( this . config . allowedAdmins && this . config . allowedAdmins . length > 0 ) {
308+ for ( const admin of this . config . allowedAdmins ) {
309+ if ( isAddress ( admin ) === true ) {
310+ ret . addresses . push ( admin )
311+ }
312+ }
313+ }
314+ ret . accessLists = this . config . allowedAdminsList
315+ return ret
316+ }
317+
318+ checkSupportedChainId ( chainId : number ) : ValidateChainId {
319+ if ( ! chainId || ! ( `${ chainId . toString ( ) } ` in this . config . supportedNetworks ) ) {
320+ OCEAN_NODE_LOGGER . error ( `Chain ID ${ chainId } is not supported` )
321+ return {
322+ validation : false ,
323+ networkRpc : ''
324+ }
325+ }
326+ return {
327+ validation : true ,
328+ networkRpc : this . config . supportedNetworks [ chainId . toString ( ) ] . rpc
329+ }
330+ }
331+
332+ async getJsonRpcProvider ( chainId : number ) : Promise < FallbackProvider > {
333+ const checkResult = this . checkSupportedChainId ( chainId )
334+ if ( ! checkResult . validation ) {
335+ return null
336+ }
337+ const blockchain = this . getBlockchain ( chainId )
338+ if ( ! blockchain ) return null
339+ return await blockchain . getProvider ( )
340+ }
341+
342+ hasP2PInterface ( ) {
343+ return this . config . hasP2P || false
344+ }
345+
346+ private dbInitPromise : Promise < Database > | null = null
347+ async getDatabase ( forceReload : boolean = false ) : Promise < Database > {
348+ if ( ! this . database || forceReload ) {
349+ if ( ! this . dbInitPromise || forceReload ) {
350+ const { dbConfig } = this . config
351+ if ( dbConfig && dbConfig . url ) {
352+ this . dbInitPromise = Database . init ( dbConfig ) . then ( ( db ) => {
353+ this . database = db
354+ return db
355+ } )
356+ }
357+ }
358+ return await this . dbInitPromise
359+ }
360+ return this . database
361+ }
362+
363+ async getValidationSignature ( ddo : string ) : Promise < any > {
364+ try {
365+ const hashedDDO = create256Hash ( ddo )
366+ const providerWallet = await this . keyManager . getEthWallet ( )
367+ const messageHash = ethers . solidityPackedKeccak256 (
368+ [ 'bytes' ] ,
369+ [ ethers . hexlify ( ethers . toUtf8Bytes ( hashedDDO ) ) ]
370+ )
371+ const signed32Bytes = await providerWallet . signMessage (
372+ new Uint8Array ( ethers . toBeArray ( messageHash ) )
373+ )
374+ const signatureSplitted = ethers . Signature . from ( signed32Bytes )
375+ const v = signatureSplitted . v <= 1 ? signatureSplitted . v + 27 : signatureSplitted . v
376+ const r = ethers . hexlify ( signatureSplitted . r ) // 32 bytes
377+ const s = ethers . hexlify ( signatureSplitted . s )
378+ return { hash : hashedDDO , publicKey : providerWallet . address , r, s, v }
379+ } catch ( error ) {
380+ OCEAN_NODE_LOGGER . logMessage ( `Validation signature error: ${ error } ` , true )
381+ return { hash : '' , publicKey : '' , r : '' , s : '' , v : '' }
382+ }
383+ }
262384}
0 commit comments