Swap Air Interpreter with AVM Worker abstraction

This commit is contained in:
Pavel Murygin 2021-12-01 17:19:28 +03:00
parent f41e8f035d
commit d6daaf05f1
8 changed files with 89 additions and 51 deletions

55
package-lock.json generated
View File

@ -10,7 +10,8 @@
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@chainsafe/libp2p-noise": "4.0.0", "@chainsafe/libp2p-noise": "4.0.0",
"@fluencelabs/avm": "0.16.0-restriction-operator.9", "@fluencelabs/avm-worker": "^0.0.2",
"@fluencelabs/avm-worker-common": "^0.0.2",
"async": "3.2.0", "async": "3.2.0",
"base64-js": "1.5.1", "base64-js": "1.5.1",
"bs58": "4.0.1", "bs58": "4.0.1",
@ -646,13 +647,32 @@
} }
}, },
"node_modules/@fluencelabs/avm": { "node_modules/@fluencelabs/avm": {
"version": "0.16.0-restriction-operator.9", "version": "0.17.4",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.16.0-restriction-operator.9.tgz", "resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.17.4.tgz",
"integrity": "sha512-34vJqo8TIho5H2+WhEAJOa6WxAPiS+c7Z3WKmRZVi+GAsZN3Hv2NiuiCFNFBmPRoD+juzHe4Dmv5cF7HZc6O6w==", "integrity": "sha512-VKD/XaEDXsP0eEgpbncBCsLyHbGDh+f7b96KbYoHld25r3C7mgEbbEVImKLaHGDUiR7ylPBxrtQhNL9MpgKwxA==",
"dependencies": { "dependencies": {
"base64-js": "1.5.1" "base64-js": "1.5.1"
} }
}, },
"node_modules/@fluencelabs/avm-worker": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm-worker/-/avm-worker-0.0.2.tgz",
"integrity": "sha512-S5ijm0QpqNSVSlj3grj6479mBfdF9O1E03xUb5N1/RiBH3fTQnGpK5u5GmbKwPJ6CvZonH7jy8tfMhGDQq5q2w==",
"dependencies": {
"@fluencelabs/avm": "^0.17.4",
"@fluencelabs/avm-worker-common": "^0.0.1"
}
},
"node_modules/@fluencelabs/avm-worker-common": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm-worker-common/-/avm-worker-common-0.0.2.tgz",
"integrity": "sha512-2SrM9gReZ3h1A9oJGFGVxLSXEnjy1qhN+GG+abA0WEVkOTup6IKAkmKdbkby+HNgZYvdSqlVpCYhcPzdtmwlGw=="
},
"node_modules/@fluencelabs/avm-worker/node_modules/@fluencelabs/avm-worker-common": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm-worker-common/-/avm-worker-common-0.0.1.tgz",
"integrity": "sha512-e3+oJD5NmEnCsKhAamZa68ogKX2AOZsWOJkORmYeAF+vDyzSa/nFxqRYa1KVOWhtlXZrKkUg7Mdk4qrZpZiuQg=="
},
"node_modules/@istanbuljs/load-nyc-config": { "node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@ -8687,13 +8707,34 @@
} }
}, },
"@fluencelabs/avm": { "@fluencelabs/avm": {
"version": "0.16.0-restriction-operator.9", "version": "0.17.4",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.16.0-restriction-operator.9.tgz", "resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.17.4.tgz",
"integrity": "sha512-34vJqo8TIho5H2+WhEAJOa6WxAPiS+c7Z3WKmRZVi+GAsZN3Hv2NiuiCFNFBmPRoD+juzHe4Dmv5cF7HZc6O6w==", "integrity": "sha512-VKD/XaEDXsP0eEgpbncBCsLyHbGDh+f7b96KbYoHld25r3C7mgEbbEVImKLaHGDUiR7ylPBxrtQhNL9MpgKwxA==",
"requires": { "requires": {
"base64-js": "1.5.1" "base64-js": "1.5.1"
} }
}, },
"@fluencelabs/avm-worker": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm-worker/-/avm-worker-0.0.2.tgz",
"integrity": "sha512-S5ijm0QpqNSVSlj3grj6479mBfdF9O1E03xUb5N1/RiBH3fTQnGpK5u5GmbKwPJ6CvZonH7jy8tfMhGDQq5q2w==",
"requires": {
"@fluencelabs/avm": "^0.17.4",
"@fluencelabs/avm-worker-common": "^0.0.1"
},
"dependencies": {
"@fluencelabs/avm-worker-common": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm-worker-common/-/avm-worker-common-0.0.1.tgz",
"integrity": "sha512-e3+oJD5NmEnCsKhAamZa68ogKX2AOZsWOJkORmYeAF+vDyzSa/nFxqRYa1KVOWhtlXZrKkUg7Mdk4qrZpZiuQg=="
}
}
},
"@fluencelabs/avm-worker-common": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm-worker-common/-/avm-worker-common-0.0.2.tgz",
"integrity": "sha512-2SrM9gReZ3h1A9oJGFGVxLSXEnjy1qhN+GG+abA0WEVkOTup6IKAkmKdbkby+HNgZYvdSqlVpCYhcPzdtmwlGw=="
},
"@istanbuljs/load-nyc-config": { "@istanbuljs/load-nyc-config": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",

View File

@ -21,7 +21,8 @@
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@chainsafe/libp2p-noise": "4.0.0", "@chainsafe/libp2p-noise": "4.0.0",
"@fluencelabs/avm": "0.16.0-restriction-operator.9", "@fluencelabs/avm-worker": "^0.0.2",
"@fluencelabs/avm-worker-common": "^0.0.2",
"async": "3.2.0", "async": "3.2.0",
"base64-js": "1.5.1", "base64-js": "1.5.1",
"bs58": "4.0.1", "bs58": "4.0.1",

View File

@ -14,14 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
import {
AirInterpreter,
CallRequestsArray,
CallResultsArray,
InterpreterResult,
LogLevel,
CallServiceResult as AvmCallServiceResult,
} from '@fluencelabs/avm';
import { Multiaddr } from 'multiaddr'; import { Multiaddr } from 'multiaddr';
import { CallServiceData, CallServiceResult, GenericCallServiceHandler, ResultCodes } from './commonTypes'; import { CallServiceData, CallServiceResult, GenericCallServiceHandler, ResultCodes } from './commonTypes';
import { CallServiceHandler as LegacyCallServiceHandler } from './compilerSupport/LegacyCallServiceHandler'; import { CallServiceHandler as LegacyCallServiceHandler } from './compilerSupport/LegacyCallServiceHandler';
@ -29,12 +21,13 @@ import { PeerIdB58 } from './commonTypes';
import { FluenceConnection } from './FluenceConnection'; import { FluenceConnection } from './FluenceConnection';
import { Particle, ParticleExecutionStage, ParticleQueueItem } from './Particle'; import { Particle, ParticleExecutionStage, ParticleQueueItem } from './Particle';
import { KeyPair } from './KeyPair'; import { KeyPair } from './KeyPair';
import { createInterpreter, dataToString } from './utils'; import { dataToString, avmLogFunction } from './utils';
import { filter, pipe, Subject, tap } from 'rxjs'; import { filter, pipe, Subject, tap } from 'rxjs';
import { RequestFlow } from './compilerSupport/v1'; import { RequestFlow } from './compilerSupport/v1';
import log from 'loglevel'; import log from 'loglevel';
import { defaultServices } from './defaultServices'; import { defaultServices } from './defaultServices';
import { instanceOf } from 'ts-pattern'; import { AvmWorker, InterpreterResult, LogLevel } from '@fluencelabs/avm-worker-common';
import Worker from '@fluencelabs/avm-worker';
/** /**
* Node of the Fluence network specified as a pair of node's multiaddr and it's peer id * Node of the Fluence network specified as a pair of node's multiaddr and it's peer id
@ -102,6 +95,11 @@ export interface PeerConfig {
* If the option is not set default TTL will be 7000 * If the option is not set default TTL will be 7000
*/ */
defaultTtlMs?: number; defaultTtlMs?: number;
/**
* Pluggable AVM worker implementation
*/
avmWorker?: AvmWorker;
} }
/** /**
@ -182,7 +180,8 @@ export class FluencePeer {
? config?.defaultTtlMs ? config?.defaultTtlMs
: DEFAULT_TTL; : DEFAULT_TTL;
this._interpreter = await createInterpreter(config?.avmLogLevel || 'off'); this._worker = config?.avmWorker || new Worker(avmLogFunction);
await this._worker.init(config?.avmLogLevel || 'off');
if (config?.connectTo) { if (config?.connectTo) {
let connectToMultiAddr: Multiaddr; let connectToMultiAddr: Multiaddr;
@ -358,7 +357,7 @@ export class FluencePeer {
private _relayPeerId: PeerIdB58 | null = null; private _relayPeerId: PeerIdB58 | null = null;
private _keyPair: KeyPair; private _keyPair: KeyPair;
private _connection: FluenceConnection; private _connection: FluenceConnection;
private _interpreter: AirInterpreter; private _worker: AvmWorker;
private _timeouts: Array<NodeJS.Timeout> = []; private _timeouts: Array<NodeJS.Timeout> = [];
private _particleQueues = new Map<string, Subject<ParticleQueueItem>>(); private _particleQueues = new Map<string, Subject<ParticleQueueItem>>();
@ -420,9 +419,9 @@ export class FluencePeer {
// force new line // force new line
filterExpiredParticles(this._expireParticle.bind(this)), filterExpiredParticles(this._expireParticle.bind(this)),
) )
.subscribe((item) => { .subscribe(async (item) => {
const particle = item.particle; const particle = item.particle;
const result = runInterpreter(this.getStatus().peerId, this._interpreter, particle, prevData); const result = await runAvmWorker(this.getStatus().peerId, this._worker, particle, prevData);
// Do not continue if there was an error in particle interpretation // Do not continue if there was an error in particle interpretation
if (!isInterpretationSuccessful(result)) { if (!isInterpretationSuccessful(result)) {
@ -585,16 +584,16 @@ function registerDefaultServices(peer: FluencePeer) {
} }
} }
function runInterpreter( async function runAvmWorker(
currentPeerId: PeerIdB58, currentPeerId: PeerIdB58,
interpreter: AirInterpreter, worker: AvmWorker,
particle: Particle, particle: Particle,
prevData: Uint8Array, prevData: Uint8Array,
): InterpreterResult { ): Promise<InterpreterResult> {
particle.logTo('debug', 'Sending particle to interpreter'); particle.logTo('debug', 'Sending particle to interpreter');
log.debug('prevData: ', dataToString(prevData)); log.debug('prevData: ', dataToString(prevData));
log.debug('data: ', dataToString(particle.data)); log.debug('data: ', dataToString(particle.data));
const interpreterResult = interpreter.invoke( const interpreterResult = await worker.run(
particle.script, particle.script,
prevData, prevData,
particle.data, particle.data,

View File

@ -16,7 +16,7 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { fromByteArray, toByteArray } from 'base64-js'; import { fromByteArray, toByteArray } from 'base64-js';
import { CallResultsArray, LogLevel } from '@fluencelabs/avm'; import { CallResultsArray, LogLevel } from '@fluencelabs/avm-worker-common';
import log from 'loglevel'; import log from 'loglevel';
import { ParticleContext } from './commonTypes'; import { ParticleContext } from './commonTypes';
import { dataToString } from './utils'; import { dataToString } from './utils';

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { CallRequest, SecurityTetraplet } from '@fluencelabs/avm'; import { SecurityTetraplet } from '@fluencelabs/avm-worker-common';
/** /**
* Peer ID's id as a base58 string (multihash/CIDv0). * Peer ID's id as a base58 string (multihash/CIDv0).

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { SecurityTetraplet } from '@fluencelabs/avm'; import { SecurityTetraplet } from '@fluencelabs/avm-worker-common';
import { match } from 'ts-pattern'; import { match } from 'ts-pattern';
import { CallParams, Fluence, FluencePeer } from '../../index'; import { CallParams, Fluence, FluencePeer } from '../../index';
import { CallServiceData, GenericCallServiceHandler, CallServiceResult, ResultCodes } from '../commonTypes'; import { CallServiceData, GenericCallServiceHandler, CallServiceResult, ResultCodes } from '../commonTypes';

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { CallServiceResult } from '@fluencelabs/avm'; import { CallServiceResult } from '@fluencelabs/avm-worker-common';
import { encode, decode } from 'bs58'; import { encode, decode } from 'bs58';
import { GenericCallServiceHandler, ResultCodes } from './commonTypes'; import { GenericCallServiceHandler, ResultCodes } from './commonTypes';

View File

@ -14,34 +14,31 @@
* limitations under the License. * limitations under the License.
*/ */
import { AirInterpreter, LogLevel as AvmLogLevel } from '@fluencelabs/avm';
import log from 'loglevel'; import log from 'loglevel';
import { CallServiceData, CallServiceResult, CallServiceResultType, ResultCodes } from './commonTypes'; import { CallServiceData, CallServiceResult, CallServiceResultType, ResultCodes } from './commonTypes';
import { AvmLoglevel, FluencePeer } from './FluencePeer'; import { FluencePeer } from './FluencePeer';
import { Particle, ParticleExecutionStage } from './Particle'; import { Particle, ParticleExecutionStage } from './Particle';
import { LogLevel as AvmLoglevel } from '@fluencelabs/avm-worker-common';
export const createInterpreter = (logLevel: AvmLoglevel): Promise<AirInterpreter> => { export const avmLogFunction = (level: AvmLoglevel, msg: string) => {
const logFn = (level: AvmLogLevel, msg: string) => { switch (level) {
switch (level) { case 'error':
case 'error': log.error(msg);
log.error(msg); break;
break;
case 'warn': case 'warn':
log.warn(msg); log.warn(msg);
break; break;
case 'info': case 'info':
log.info(msg); log.info(msg);
break; break;
case 'debug': case 'debug':
case 'trace': case 'trace':
log.log(msg); log.log(msg);
break; break;
} }
};
return AirInterpreter.create(logLevel, logFn);
}; };
export const MakeServiceCall = (fn: (args: any[]) => CallServiceResultType) => { export const MakeServiceCall = (fn: (args: any[]) => CallServiceResultType) => {