Improvements (#44)

* Add more detailed information when the particle is sent to incorrect peers

* Throwing custom error in case of version incompatibility
This commit is contained in:
Pavel 2021-04-27 17:08:18 +03:00 committed by GitHub
parent d84d9fd7ea
commit 8c372cd0c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 14 deletions

View File

@ -246,6 +246,23 @@ describe('Typescript usage suite', () => {
instruction: 'call %init_peer_id% ("peer" "identify") [] res', instruction: 'call %init_peer_id% ("peer" "identify") [] res',
}); });
}); });
it('Should throw correct error when the client tries to send a particle not to the relay', async () => {
// arrange
client = await createClient();
// act
const [req, promise] = new RequestFlowBuilder()
.withRawScript('(call "incorrect_peer_id" ("any" "service") [])')
.buildWithErrorHandling();
await client.initiateFlow(req);
// assert
await expect(promise).rejects.toMatch(
'Particle is expected to be sent to only the single peer (relay which client is connected to)',
);
});
}); });
async function callIdentifyOnInitPeerId(client: FluenceClient): Promise<string[]> { async function callIdentifyOnInitPeerId(client: FluenceClient): Promise<string[]> {

View File

@ -112,7 +112,7 @@ export class ClientImpl implements FluenceClient {
request.handler.combineWith(this.aquaCallHandler); request.handler.combineWith(this.aquaCallHandler);
this.requests.set(request.id, request); this.requests.set(request.id, request);
await this.processRequest(request); this.processRequest(request);
} }
async executeIncomingParticle(particle: Particle) { async executeIncomingParticle(particle: Particle) {
@ -130,7 +130,7 @@ export class ClientImpl implements FluenceClient {
await this.processRequest(request); await this.processRequest(request);
} }
private async processRequest(request: RequestFlow): Promise<void> { private processRequest(request: RequestFlow) {
try { try {
this.currentRequestId = request.id; this.currentRequestId = request.id;
request.execute(this.interpreter, this.connection, this.relayPeerId); request.execute(this.interpreter, this.connection, this.relayPeerId);

View File

@ -54,6 +54,12 @@ export interface FluenceConnectionOptions {
dialTimeout?: number; dialTimeout?: number;
} }
export class VersionIncompatibleError extends Error {
constructor() {
super('Current version of JS SDK is incompatible with the connected Fluence node. Please update JS SDK');
}
}
export class FluenceConnection { export class FluenceConnection {
private readonly selfPeerId: PeerId; private readonly selfPeerId: PeerId;
private node: Peer; private node: Peer;
@ -89,7 +95,7 @@ export class FluenceConnection {
private async createPeer(options?: FluenceConnectionOptions) { private async createPeer(options?: FluenceConnectionOptions) {
const peerInfo = this.selfPeerId; const peerInfo = this.selfPeerId;
const transportKey = Websockets.prototype[Symbol.toStringTag] const transportKey = Websockets.prototype[Symbol.toStringTag];
this.node = await Peer.create({ this.node = await Peer.create({
peerId: peerInfo, peerId: peerInfo,
modules: { modules: {
@ -100,9 +106,9 @@ export class FluenceConnection {
config: { config: {
transport: { transport: {
[transportKey]: { [transportKey]: {
filter: allow_all filter: allow_all,
} },
} },
}, },
dialer: { dialer: {
timeout: options?.dialTimeout, timeout: options?.dialTimeout,
@ -116,7 +122,13 @@ export class FluenceConnection {
log.trace(`dialing to the node with client's address: ` + this.node.peerId.toB58String()); log.trace(`dialing to the node with client's address: ` + this.node.peerId.toB58String());
await this.node.dial(this.address); try {
await this.node.dial(this.address);
} catch (e) {
if (e.name === 'AggregateError' && e._errors[0].code === 'ERR_ENCRYPTION_FAILED') {
throw new VersionIncompatibleError();
}
}
let _this = this; let _this = this;

View File

@ -66,6 +66,7 @@ export class RequestFlow {
const interpreterOutcome = this.runInterpreter(interpreter); const interpreterOutcome = this.runInterpreter(interpreter);
log.debug('inner interpreter outcome:', { log.debug('inner interpreter outcome:', {
particleId: this.getParticle()?.id,
ret_code: interpreterOutcome.ret_code, ret_code: interpreterOutcome.ret_code,
error_message: interpreterOutcome.error_message, error_message: interpreterOutcome.error_message,
next_peer_pks: interpreterOutcome.next_peer_pks, next_peer_pks: interpreterOutcome.next_peer_pks,
@ -86,25 +87,31 @@ export class RequestFlow {
// we only expect a single possible peer id to send particle further // we only expect a single possible peer id to send particle further
if (nextPeers.length > 1) { if (nextPeers.length > 1) {
throw new Error( this.throwIncorrectNextPeerPks(nextPeers);
'Particle is expected to be sent to only the single peer (relay which client is connected to)',
);
} }
// this peer id must be the relay, the client is connected to // this peer id must be the relay, the client is connected to
if (!relayPeerId || nextPeers[0] !== relayPeerId) { if (!relayPeerId || nextPeers[0] !== relayPeerId) {
throw new Error( this.throwIncorrectNextPeerPks(nextPeers);
'Particle is expected to be sent to only the single peer (relay which client is connected to)',
);
} }
if (!connection) { if (!connection) {
throw new Error('Cannot send particle: non connected'); this.raiseError('Cannot send particle: non connected');
} }
this.sendIntoConnection(connection); this.sendIntoConnection(connection);
} }
private throwIncorrectNextPeerPks(nextPeers: PeerIdB58[]) {
this.raiseError(
`Particle is expected to be sent to only the single peer (relay which client is connected to).
particle id: ${this.getParticle()?.id}
next peers: ${nextPeers.join(' ')}
relay peer id: ${this.relayPeerId}
`,
);
}
async initState(peerId: PeerId): Promise<void> { async initState(peerId: PeerId): Promise<void> {
const id = this.id; const id = this.id;
let currentTime = Date.now(); let currentTime = Date.now();