From 56c849bb64700db84e317e1d19ae2951b094e2df Mon Sep 17 00:00:00 2001 From: DieMyst Date: Tue, 14 Feb 2023 08:38:15 +0400 Subject: [PATCH] refactoring, round robin --- .../gateway/aqua-compiled/rpc.d.ts | 122 ++- .../gateway/aqua-compiled/rpc.js | 819 +++++++++++++++++- .../gateway/aqua/rpc.aqua | 48 +- .../gateway/config.json | 6 + .../gateway/package-lock.json | 22 +- .../gateway/package.json | 6 +- .../gateway/src/arguments.js | 25 + .../gateway/src/config.js | 6 + .../gateway/src/index.js | 77 +- 9 files changed, 1033 insertions(+), 98 deletions(-) create mode 100644 aqua-examples/decentralized-blockchain-gateway/gateway/config.json create mode 100644 aqua-examples/decentralized-blockchain-gateway/gateway/src/arguments.js create mode 100644 aqua-examples/decentralized-blockchain-gateway/gateway/src/config.js diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.d.ts b/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.d.ts index f578b17..9ff0d9d 100644 --- a/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.d.ts +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.d.ts @@ -19,6 +19,7 @@ import { // Services export interface LoggerDef { log: (s: string[], callParams: CallParams$$<'s'>) => void | Promise; + logCall: (s: string, callParams: CallParams$$<'s'>) => void | Promise; } export function registerLogger(service: LoggerDef): void; export function registerLogger(serviceId: string, service: LoggerDef): void; @@ -26,19 +27,134 @@ export function registerLogger(peer: FluencePeer, service: LoggerDef): void; export function registerLogger(peer: FluencePeer, serviceId: string, service: LoggerDef): void; export interface EthCallerDef { - eth_call: (uri: string, method: string, json_args: string[], callParams: CallParams$$<'uri' | 'method' | 'json_args'>) => { error: string; success: boolean; value: string; } | Promise<{ error: string; success: boolean; value: string; }>; + eth_call: (uri: string, method: string, jsonArgs: string[], callParams: CallParams$$<'uri' | 'method' | 'jsonArgs'>) => { error: string; success: boolean; value: string; } | Promise<{ error: string; success: boolean; value: string; }>; } export function registerEthCaller(serviceId: string, service: EthCallerDef): void; export function registerEthCaller(peer: FluencePeer, serviceId: string, service: EthCallerDef): void; +export interface CounterDef { + incrementAndReturn: (callParams: CallParams$$) => number | Promise; +} +export function registerCounter(service: CounterDef): void; +export function registerCounter(serviceId: string, service: CounterDef): void; +export function registerCounter(peer: FluencePeer, service: CounterDef): void; +export function registerCounter(peer: FluencePeer, serviceId: string, service: CounterDef): void; + +export interface NumOpDef { + identity: (n: number, callParams: CallParams$$<'n'>) => number | Promise; +} +export function registerNumOp(service: NumOpDef): void; +export function registerNumOp(serviceId: string, service: NumOpDef): void; +export function registerNumOp(peer: FluencePeer, service: NumOpDef): void; +export function registerNumOp(peer: FluencePeer, serviceId: string, service: NumOpDef): void; + // Functions +export type RoundRobinEthResult = { error: string; success: boolean; value: string; } +export function roundRobinEth( + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + counterServiceId: string, + counterPeerId: string, + config?: {ttl?: number} +): Promise; + +export function roundRobinEth( + peer: FluencePeer, + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + counterServiceId: string, + counterPeerId: string, + config?: {ttl?: number} +): Promise; + + +export type EmptyResult = { error: string; success: boolean; value: string; } +export function empty( + config?: {ttl?: number} +): Promise; + +export function empty( + peer: FluencePeer, + config?: {ttl?: number} +): Promise; + + +export type RandomLoadBalancingResult = { error: string; success: boolean; value: string; } +export function randomLoadBalancing( + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + callFunc: (arg0: string, arg1: string, arg2: string[], arg3: string, callParams: CallParams$$<'arg0' | 'arg1' | 'arg2' | 'arg3'>) => { error: string; success: boolean; value: string; } | Promise<{ error: string; success: boolean; value: string; }>, + config?: {ttl?: number} +): Promise; + +export function randomLoadBalancing( + peer: FluencePeer, + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + callFunc: (arg0: string, arg1: string, arg2: string[], arg3: string, callParams: CallParams$$<'arg0' | 'arg1' | 'arg2' | 'arg3'>) => { error: string; success: boolean; value: string; } | Promise<{ error: string; success: boolean; value: string; }>, + config?: {ttl?: number} +): Promise; + + +export type RandomLoadBalancingEthResult = { error: string; success: boolean; value: string; } +export function randomLoadBalancingEth( + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + config?: {ttl?: number} +): Promise; + +export function randomLoadBalancingEth( + peer: FluencePeer, + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + config?: {ttl?: number} +): Promise; + + +export type RoundRobinResult = { error: string; success: boolean; value: string; } +export function roundRobin( + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + counterServiceId: string, + counterPeerId: string, + callFunc: (arg0: string, arg1: string, arg2: string[], arg3: string, callParams: CallParams$$<'arg0' | 'arg1' | 'arg2' | 'arg3'>) => { error: string; success: boolean; value: string; } | Promise<{ error: string; success: boolean; value: string; }>, + config?: {ttl?: number} +): Promise; + +export function roundRobin( + peer: FluencePeer, + uris: string[], + method: string, + jsonArgs: string[], + serviceId: string, + counterServiceId: string, + counterPeerId: string, + callFunc: (arg0: string, arg1: string, arg2: string[], arg3: string, callParams: CallParams$$<'arg0' | 'arg1' | 'arg2' | 'arg3'>) => { error: string; success: boolean; value: string; } | Promise<{ error: string; success: boolean; value: string; }>, + config?: {ttl?: number} +): Promise; + + export type CallResult = { error: string; success: boolean; value: string; } export function call( uri: string, method: string, - json_args: string[], + jsonArgs: string[], serviceId: string, config?: {ttl?: number} ): Promise; @@ -47,7 +163,7 @@ export function call( peer: FluencePeer, uri: string, method: string, - json_args: string[], + jsonArgs: string[], serviceId: string, config?: {ttl?: number} ): Promise; diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.js b/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.js index 9c06d08..99419a3 100644 --- a/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.js +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/aqua-compiled/rpc.js @@ -43,6 +43,21 @@ export function registerLogger(...args) { "codomain" : { "tag" : "nil" } + }, + "logCall" : { + "tag" : "arrow", + "domain" : { + "tag" : "labeledProduct", + "fields" : { + "s" : { + "tag" : "scalar", + "name" : "string" + } + } + }, + "codomain" : { + "tag" : "nil" + } } } } @@ -74,7 +89,7 @@ export function registerEthCaller(...args) { "tag" : "scalar", "name" : "string" }, - "json_args" : { + "jsonArgs" : { "tag" : "array", "type" : { "tag" : "scalar", @@ -88,7 +103,7 @@ export function registerEthCaller(...args) { "items" : [ { "tag" : "struct", - "name" : "JsonString", + "name" : "EthResult", "fields" : { "error" : { "tag" : "scalar", @@ -113,9 +128,81 @@ export function registerEthCaller(...args) { ); } + + + + +export function registerCounter(...args) { + registerService$$( + args, + { + "defaultServiceId" : "counter", + "functions" : { + "tag" : "labeledProduct", + "fields" : { + "incrementAndReturn" : { + "tag" : "arrow", + "domain" : { + "tag" : "nil" + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "scalar", + "name" : "u32" + } + ] + } + } + } + } +} + ); +} + + + + + +export function registerNumOp(...args) { + registerService$$( + args, + { + "defaultServiceId" : "op", + "functions" : { + "tag" : "labeledProduct", + "fields" : { + "identity" : { + "tag" : "arrow", + "domain" : { + "tag" : "labeledProduct", + "fields" : { + "n" : { + "tag" : "scalar", + "name" : "u64" + } + } + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "scalar", + "name" : "i64" + } + ] + } + } + } + } +} + ); +} + // Functions -export function call(...args) { +export function roundRobinEth(...args) { let script = ` (xor @@ -125,46 +212,79 @@ export function call(...args) { (seq (seq (seq - (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) - (call %init_peer_id% ("getDataSrv" "uri") [] uri) + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "uris") [] uris) + ) + (call %init_peer_id% ("getDataSrv" "method") [] method) + ) + (call %init_peer_id% ("getDataSrv" "jsonArgs") [] jsonArgs) + ) + (call %init_peer_id% ("getDataSrv" "serviceId") [] serviceId) + ) + (call %init_peer_id% ("getDataSrv" "counterServiceId") [] counterServiceId) + ) + (call %init_peer_id% ("getDataSrv" "counterPeerId") [] counterPeerId) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call counterPeerId (counterServiceId "incrementAndReturn") [] requestNumber) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) ) - (call %init_peer_id% ("getDataSrv" "method") [] method) ) - (call %init_peer_id% ("getDataSrv" "json_args") [] json_args) ) - (call %init_peer_id% ("getDataSrv" "serviceId") [] serviceId) + (xor + (seq + (seq + (call %init_peer_id% ("op" "array_length") [uris] array_length) + (call %init_peer_id% ("math" "rem") [requestNumber array_length] rem) + ) + (call %init_peer_id% ("logger" "logCall") [uris.$.[rem]!]) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) ) (xor - (call -relay- (serviceId "eth_call") [uri method json_args] res) - (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + (call -relay- (serviceId "eth_call") [uris.$.[rem]! method jsonArgs] res) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) ) ) (xor (call %init_peer_id% ("callbackSrv" "response") [res]) - (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 4]) ) ) - (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 5]) ) ` return callFunction$$( args, { - "functionName" : "call", + "functionName" : "roundRobinEth", "arrow" : { "tag" : "arrow", "domain" : { "tag" : "labeledProduct", "fields" : { - "uri" : { - "tag" : "scalar", - "name" : "string" + "uris" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } }, "method" : { "tag" : "scalar", "name" : "string" }, - "json_args" : { + "jsonArgs" : { "tag" : "array", "type" : { "tag" : "scalar", @@ -174,6 +294,14 @@ export function call(...args) { "serviceId" : { "tag" : "scalar", "name" : "string" + }, + "counterServiceId" : { + "tag" : "scalar", + "name" : "string" + }, + "counterPeerId" : { + "tag" : "scalar", + "name" : "string" } } }, @@ -182,7 +310,662 @@ export function call(...args) { "items" : [ { "tag" : "struct", - "name" : "JsonString", + "name" : "EthResult", + "fields" : { + "error" : { + "tag" : "scalar", + "name" : "string" + }, + "success" : { + "tag" : "scalar", + "name" : "bool" + }, + "value" : { + "tag" : "scalar", + "name" : "string" + } + } + } + ] + } + }, + "names" : { + "relay" : "-relay-", + "getDataSrv" : "getDataSrv", + "callbackSrv" : "callbackSrv", + "responseSrv" : "callbackSrv", + "responseFnName" : "response", + "errorHandlingSrv" : "errorHandlingSrv", + "errorFnName" : "error" + } +}, + script + ) +} + + +export function empty(...args) { + + let script = ` + (xor + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("json" "obj") ["error" "" "success" true "value" ""] EthResult_obj) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [EthResult_obj]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ` + return callFunction$$( + args, + { + "functionName" : "empty", + "arrow" : { + "tag" : "arrow", + "domain" : { + "tag" : "labeledProduct", + "fields" : { + + } + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "struct", + "name" : "EthResult", + "fields" : { + "error" : { + "tag" : "scalar", + "name" : "string" + }, + "success" : { + "tag" : "scalar", + "name" : "bool" + }, + "value" : { + "tag" : "scalar", + "name" : "string" + } + } + } + ] + } + }, + "names" : { + "relay" : "-relay-", + "getDataSrv" : "getDataSrv", + "callbackSrv" : "callbackSrv", + "responseSrv" : "callbackSrv", + "responseFnName" : "response", + "errorHandlingSrv" : "errorHandlingSrv", + "errorFnName" : "error" + } +}, + script + ) +} + + +export function randomLoadBalancing(...args) { + + let script = ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "uris") [] uris) + ) + (call %init_peer_id% ("getDataSrv" "method") [] method) + ) + (call %init_peer_id% ("getDataSrv" "jsonArgs") [] jsonArgs) + ) + (call %init_peer_id% ("getDataSrv" "serviceId") [] serviceId) + ) + (xor + (seq + (seq + (seq + (seq + (call %init_peer_id% ("peer" "timestamp_sec") [] timestamp_sec) + (call %init_peer_id% ("op" "identity") [timestamp_sec] time) + ) + (call %init_peer_id% ("op" "array_length") [uris] array_length) + ) + (call %init_peer_id% ("math" "rem") [time array_length] rem) + ) + (call %init_peer_id% ("logger" "logCall") [uris.$.[rem]!]) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "callFunc") [uris.$.[rem]! method jsonArgs serviceId] init_call_res0) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [init_call_res0]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 4]) + ) + ` + return callFunction$$( + args, + { + "functionName" : "randomLoadBalancing", + "arrow" : { + "tag" : "arrow", + "domain" : { + "tag" : "labeledProduct", + "fields" : { + "uris" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + "method" : { + "tag" : "scalar", + "name" : "string" + }, + "jsonArgs" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + "serviceId" : { + "tag" : "scalar", + "name" : "string" + }, + "callFunc" : { + "tag" : "arrow", + "domain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "scalar", + "name" : "string" + }, + { + "tag" : "scalar", + "name" : "string" + }, + { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + { + "tag" : "scalar", + "name" : "string" + } + ] + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "struct", + "name" : "EthResult", + "fields" : { + "error" : { + "tag" : "scalar", + "name" : "string" + }, + "success" : { + "tag" : "scalar", + "name" : "bool" + }, + "value" : { + "tag" : "scalar", + "name" : "string" + } + } + } + ] + } + } + } + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "struct", + "name" : "EthResult", + "fields" : { + "error" : { + "tag" : "scalar", + "name" : "string" + }, + "success" : { + "tag" : "scalar", + "name" : "bool" + }, + "value" : { + "tag" : "scalar", + "name" : "string" + } + } + } + ] + } + }, + "names" : { + "relay" : "-relay-", + "getDataSrv" : "getDataSrv", + "callbackSrv" : "callbackSrv", + "responseSrv" : "callbackSrv", + "responseFnName" : "response", + "errorHandlingSrv" : "errorHandlingSrv", + "errorFnName" : "error" + } +}, + script + ) +} + + +export function randomLoadBalancingEth(...args) { + + let script = ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "uris") [] uris) + ) + (call %init_peer_id% ("getDataSrv" "method") [] method) + ) + (call %init_peer_id% ("getDataSrv" "jsonArgs") [] jsonArgs) + ) + (call %init_peer_id% ("getDataSrv" "serviceId") [] serviceId) + ) + (xor + (seq + (seq + (seq + (seq + (call %init_peer_id% ("peer" "timestamp_sec") [] timestamp_sec) + (call %init_peer_id% ("op" "identity") [timestamp_sec] time) + ) + (call %init_peer_id% ("op" "array_length") [uris] array_length) + ) + (call %init_peer_id% ("math" "rem") [time array_length] rem) + ) + (call %init_peer_id% ("logger" "logCall") [uris.$.[rem]!]) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + (xor + (call -relay- (serviceId "eth_call") [uris.$.[rem]! method jsonArgs] res) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [res]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 4]) + ) + ` + return callFunction$$( + args, + { + "functionName" : "randomLoadBalancingEth", + "arrow" : { + "tag" : "arrow", + "domain" : { + "tag" : "labeledProduct", + "fields" : { + "uris" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + "method" : { + "tag" : "scalar", + "name" : "string" + }, + "jsonArgs" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + "serviceId" : { + "tag" : "scalar", + "name" : "string" + } + } + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "struct", + "name" : "EthResult", + "fields" : { + "error" : { + "tag" : "scalar", + "name" : "string" + }, + "success" : { + "tag" : "scalar", + "name" : "bool" + }, + "value" : { + "tag" : "scalar", + "name" : "string" + } + } + } + ] + } + }, + "names" : { + "relay" : "-relay-", + "getDataSrv" : "getDataSrv", + "callbackSrv" : "callbackSrv", + "responseSrv" : "callbackSrv", + "responseFnName" : "response", + "errorHandlingSrv" : "errorHandlingSrv", + "errorFnName" : "error" + } +}, + script + ) +} + + +export function roundRobin(...args) { + + let script = ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "uris") [] uris) + ) + (call %init_peer_id% ("getDataSrv" "method") [] method) + ) + (call %init_peer_id% ("getDataSrv" "jsonArgs") [] jsonArgs) + ) + (call %init_peer_id% ("getDataSrv" "serviceId") [] serviceId) + ) + (call %init_peer_id% ("getDataSrv" "counterServiceId") [] counterServiceId) + ) + (call %init_peer_id% ("getDataSrv" "counterPeerId") [] counterPeerId) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call counterPeerId (counterServiceId "incrementAndReturn") [] requestNumber) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (xor + (seq + (seq + (call %init_peer_id% ("op" "array_length") [uris] array_length) + (call %init_peer_id% ("math" "rem") [requestNumber array_length] rem) + ) + (call %init_peer_id% ("logger" "logCall") [uris.$.[rem]!]) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "callFunc") [uris.$.[rem]! method jsonArgs serviceId] init_call_res0) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [init_call_res0]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 4]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 5]) + ) + ` + return callFunction$$( + args, + { + "functionName" : "roundRobin", + "arrow" : { + "tag" : "arrow", + "domain" : { + "tag" : "labeledProduct", + "fields" : { + "uris" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + "method" : { + "tag" : "scalar", + "name" : "string" + }, + "jsonArgs" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + "serviceId" : { + "tag" : "scalar", + "name" : "string" + }, + "counterServiceId" : { + "tag" : "scalar", + "name" : "string" + }, + "counterPeerId" : { + "tag" : "scalar", + "name" : "string" + }, + "callFunc" : { + "tag" : "arrow", + "domain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "scalar", + "name" : "string" + }, + { + "tag" : "scalar", + "name" : "string" + }, + { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + { + "tag" : "scalar", + "name" : "string" + } + ] + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "struct", + "name" : "EthResult", + "fields" : { + "error" : { + "tag" : "scalar", + "name" : "string" + }, + "success" : { + "tag" : "scalar", + "name" : "bool" + }, + "value" : { + "tag" : "scalar", + "name" : "string" + } + } + } + ] + } + } + } + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "struct", + "name" : "EthResult", + "fields" : { + "error" : { + "tag" : "scalar", + "name" : "string" + }, + "success" : { + "tag" : "scalar", + "name" : "bool" + }, + "value" : { + "tag" : "scalar", + "name" : "string" + } + } + } + ] + } + }, + "names" : { + "relay" : "-relay-", + "getDataSrv" : "getDataSrv", + "callbackSrv" : "callbackSrv", + "responseSrv" : "callbackSrv", + "responseFnName" : "response", + "errorHandlingSrv" : "errorHandlingSrv", + "errorFnName" : "error" + } +}, + script + ) +} + + +export function call(...args) { + + let script = ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "uri") [] uri) + ) + (call %init_peer_id% ("getDataSrv" "method") [] method) + ) + (call %init_peer_id% ("getDataSrv" "jsonArgs") [] jsonArgs) + ) + (call %init_peer_id% ("getDataSrv" "serviceId") [] serviceId) + ) + (xor + (call -relay- (serviceId "eth_call") [uri method jsonArgs] res) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [res]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) + ) + ` + return callFunction$$( + args, + { + "functionName" : "call", + "arrow" : { + "tag" : "arrow", + "domain" : { + "tag" : "labeledProduct", + "fields" : { + "uri" : { + "tag" : "scalar", + "name" : "string" + }, + "method" : { + "tag" : "scalar", + "name" : "string" + }, + "jsonArgs" : { + "tag" : "array", + "type" : { + "tag" : "scalar", + "name" : "string" + } + }, + "serviceId" : { + "tag" : "scalar", + "name" : "string" + } + } + }, + "codomain" : { + "tag" : "unlabeledProduct", + "items" : [ + { + "tag" : "struct", + "name" : "EthResult", "fields" : { "error" : { "tag" : "scalar", diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/aqua/rpc.aqua b/aqua-examples/decentralized-blockchain-gateway/gateway/aqua/rpc.aqua index 9701f9e..f648d69 100644 --- a/aqua-examples/decentralized-blockchain-gateway/gateway/aqua/rpc.aqua +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/aqua/rpc.aqua @@ -1,16 +1,54 @@ -data JsonString: +import "@fluencelabs/aqua-lib/builtin.aqua" + +export randomLoadBalancingEth, roundRobinEth, Counter, Logger + + + +data EthResult: value: string success: bool error: string service Logger("logger"): log(s: []string) + logCall(s: string) + +service NumOp("op"): + identity(n: u64) -> i64 + +service Counter("counter"): + incrementAndReturn() -> u32 + +func empty() -> EthResult: + <- EthResult(value = "", success = true, error = "") service EthCaller: - eth_call(uri: string, method: string, json_args: []string) -> JsonString + eth_call(uri: string, method: string, jsonArgs: []string) -> EthResult -func call(uri: string, method: string, json_args: []string, serviceId: string) -> JsonString: +func call(uri: string, method: string, jsonArgs: []string, serviceId: string) -> EthResult: EthCaller serviceId on HOST_PEER_ID: - res <- EthCaller.eth_call(uri, method, json_args) - <- res \ No newline at end of file + res <- EthCaller.eth_call(uri, method, jsonArgs) + <- res + +func randomLoadBalancing(uris: []string, method: string, jsonArgs: []string, serviceId: string, callFunc: string, string, []string, string -> EthResult) -> EthResult: + on INIT_PEER_ID: + time <- NumOp.identity(Peer.timestamp_sec()) + providerNumber = time % Op.array_length(uris) + Logger.logCall(uris[providerNumber]) + <- callFunc(uris[providerNumber], method, jsonArgs, serviceId) + +func randomLoadBalancingEth(uris: []string, method: string, jsonArgs: []string, serviceId: string) -> EthResult: + <- randomLoadBalancing(uris, method, jsonArgs, serviceId, call) + +func roundRobin(uris: []string, method: string, jsonArgs: []string, serviceId: string, counterServiceId: string, counterPeerId: string, callFunc: string, string, []string, string -> EthResult) -> EthResult: + on counterPeerId: + Counter counterServiceId + requestNumber <- Counter.incrementAndReturn() + on INIT_PEER_ID: + providerNumber = requestNumber % Op.array_length(uris) + Logger.logCall(uris[providerNumber]) + <- callFunc(uris[providerNumber], method, jsonArgs, serviceId) + +func roundRobinEth(uris: []string, method: string, jsonArgs: []string, serviceId: string, counterServiceId: string, counterPeerId: string) -> EthResult: + <- roundRobin(uris, method, jsonArgs, serviceId, counterServiceId, counterPeerId, call) \ No newline at end of file diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/config.json b/aqua-examples/decentralized-blockchain-gateway/gateway/config.json new file mode 100644 index 0000000..9878224 --- /dev/null +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/config.json @@ -0,0 +1,6 @@ +{ + "providers": [ + "https://goerli.infura.io/v3/77214656b25f4cad9cd2540c6d40c301", + "https://goerli.infura.io/v3/c48f3b538f154204ad53d04aa8990544" + ] +} \ No newline at end of file diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/package-lock.json b/aqua-examples/decentralized-blockchain-gateway/gateway/package-lock.json index 986cb04..8c86ed4 100644 --- a/aqua-examples/decentralized-blockchain-gateway/gateway/package-lock.json +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/package-lock.json @@ -1063,7 +1063,7 @@ }, "node_modules/@fluencelabs/avm": { "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.35.3.tgz", + "resolved": "https://npm.fluence.dev/@fluencelabs%2favm/-/avm-0.35.3.tgz", "integrity": "sha512-Y5mPPCmAUUKc5CDO12IL8mGEreWa7maVdX0MWCAH4+GvfLPFN1FxOMSKRYEtvkyVEL88pc9pd8cm5IRCBkFthg==" }, "node_modules/@fluencelabs/connection": { @@ -1127,7 +1127,7 @@ }, "node_modules/@fluencelabs/fluence": { "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.28.0.tgz", + "resolved": "https://npm.fluence.dev/@fluencelabs%2ffluence/-/fluence-0.28.0.tgz", "integrity": "sha512-SXb2vjTj8m/nw4jEILV0tu9VIFprGo8mNb2nOB5btxdsOI8GzQZkpGzTLrSd/+UagIo2GdxAu0GhBP8dxZXaqg==", "dependencies": { "@fluencelabs/avm": "0.35.3", @@ -1159,12 +1159,12 @@ }, "node_modules/@fluencelabs/fluence/node_modules/base-x": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "resolved": "https://npm.fluence.dev/base-x/-/base-x-4.0.0.tgz", "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" }, "node_modules/@fluencelabs/fluence/node_modules/bs58": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "resolved": "https://npm.fluence.dev/bs58/-/bs58-5.0.0.tgz", "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", "dependencies": { "base-x": "^4.0.0" @@ -1172,7 +1172,7 @@ }, "node_modules/@fluencelabs/fluence/node_modules/buffer": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "resolved": "https://npm.fluence.dev/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { @@ -1195,7 +1195,7 @@ }, "node_modules/@fluencelabs/fluence/node_modules/cids": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/cids/-/cids-1.1.9.tgz", + "resolved": "https://npm.fluence.dev/cids/-/cids-1.1.9.tgz", "integrity": "sha512-l11hWRfugIcbGuTZwAM5PwpjPPjyb6UZOGwlHSnOBV5o07XhQ4gNpBN67FbODvpjyHtd+0Xs6KNvUcGBiDRsdg==", "deprecated": "This module has been superseded by the multiformats module", "dependencies": { @@ -1211,7 +1211,7 @@ }, "node_modules/@fluencelabs/fluence/node_modules/multibase": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-4.0.6.tgz", + "resolved": "https://npm.fluence.dev/multibase/-/multibase-4.0.6.tgz", "integrity": "sha512-x23pDe5+svdLz/k5JPGCVdfn7Q5mZVMBETiC+ORfO+sor9Sgs0smJzAjfTbM5tckeCqnaUuMYoz+k3RXMmJClQ==", "deprecated": "This module has been superseded by the multiformats module", "dependencies": { @@ -1224,7 +1224,7 @@ }, "node_modules/@fluencelabs/fluence/node_modules/multicodec": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-3.2.1.tgz", + "resolved": "https://npm.fluence.dev/multicodec/-/multicodec-3.2.1.tgz", "integrity": "sha512-+expTPftro8VAW8kfvcuNNNBgb9gPeNYV9dn+z1kJRWF2vih+/S79f2RVeIwmrJBUJ6NT9IUPWnZDQvegEh5pw==", "deprecated": "This module has been superseded by the multiformats module", "dependencies": { @@ -1234,12 +1234,12 @@ }, "node_modules/@fluencelabs/fluence/node_modules/multicodec/node_modules/varint": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "resolved": "https://npm.fluence.dev/varint/-/varint-6.0.0.tgz", "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" }, "node_modules/@fluencelabs/fluence/node_modules/multihashes": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-4.0.3.tgz", + "resolved": "https://npm.fluence.dev/multihashes/-/multihashes-4.0.3.tgz", "integrity": "sha512-0AhMH7Iu95XjDLxIeuCOOE4t9+vQZsACyKZ9Fxw2pcsRmlX4iCn1mby0hS0bb+nQOVpdQYWPpnyusw4da5RPhA==", "dependencies": { "multibase": "^4.0.1", @@ -1253,7 +1253,7 @@ }, "node_modules/@fluencelabs/fluence/node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "resolved": "https://npm.fluence.dev/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/package.json b/aqua-examples/decentralized-blockchain-gateway/gateway/package.json index 3624422..31a49a1 100644 --- a/aqua-examples/decentralized-blockchain-gateway/gateway/package.json +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/package.json @@ -1,11 +1,11 @@ { "name": "@fluencelabs/aqua-eth-gateway", - "version": "0.0.9", + "version": "0.0.10", "description": "", "main": "src/index.js", "type": "module", "scripts": { - "run:example": "node src/index.js 3000 \"/dns4/kras-02.fluence.dev/tcp/19001/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf\" \"https://goerli.infura.io/v3/c48f3b538f154204ad53d04aa8990544\" \"d071085b-639c-4716-8bf3-d86b13210173\"", + "run:example": "node src/index.js 3000 \"/dns4/kras-02.fluence.dev/tcp/19001/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf\" \"config.json\" \"25bf2293-7503-4a01-af00-d1b7d089ca37\"", "run": "node src/index.js", "req": "node web3run.js" }, @@ -15,7 +15,7 @@ "files": [ "src/*", "aqua/*", - "aqua-compiled/" + "aqua-compiled/*" ], "author": "Fluence Labs", "license": "Apache-2.0", diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/src/arguments.js b/aqua-examples/decentralized-blockchain-gateway/gateway/src/arguments.js new file mode 100644 index 0000000..7ebc49c --- /dev/null +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/src/arguments.js @@ -0,0 +1,25 @@ +export function readArguments(args) { + const port = args[0] + const relay = args[1] + const configPath = args[2] + const serviceId = args[3] + + let errors = [] + if (!port) { + errors.push("Specify port") + } + if (!relay) { + errors.push("Specify Fluence peer address") + } + if (!configPath) { + errors.push("Specify config with uri to ethereum RPC providers") + } + if (!serviceId) { + errors.push("Specify id to ethereum Aqua service") + } + + return { + port, relay, configPath, serviceId, errors, + help: "Example: aqua-eth-gateway " + } +} \ No newline at end of file diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/src/config.js b/aqua-examples/decentralized-blockchain-gateway/gateway/src/config.js new file mode 100644 index 0000000..2689819 --- /dev/null +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/src/config.js @@ -0,0 +1,6 @@ +import fs from 'fs'; + +export function readConfig(path) { + const rawdata = fs.readFileSync(path); + return JSON.parse(rawdata); +} diff --git a/aqua-examples/decentralized-blockchain-gateway/gateway/src/index.js b/aqua-examples/decentralized-blockchain-gateway/gateway/src/index.js index f165a48..41c8a04 100644 --- a/aqua-examples/decentralized-blockchain-gateway/gateway/src/index.js +++ b/aqua-examples/decentralized-blockchain-gateway/gateway/src/index.js @@ -2,66 +2,24 @@ "use strict"; -handleEPIPE(process.stderr) -handleEPIPE(process.stdout) -function handleEPIPE(stream) { - stream.on('error', onerror) - function onerror(err) { - if (err.code === 'EPIPE') { - stream._write = noopWrite - stream._writev = noopWritev - stream._read = noopRead - return stream.removeListener('error', onerror) - } - if (EE.listenerCount(stream, 'error') === 1) { - stream.removeListener('error', onerror) - stream.emit('error', err) - } - } -} -function noopWrite(chunk, enc, cb) { - cb() -} -function noopRead() { - this.push('') -} -function noopWritev(chunks, cb) { - cb() -} - import express from "express"; import bodyParser from "body-parser"; import { JSONRPCServer } from "json-rpc-2.0"; import { FluencePeer } from "@fluencelabs/fluence"; -import {call, registerLogger} from "../aqua-compiled/rpc.js"; +import {call, randomLoadBalancingEth, registerLogger} from "../aqua-compiled/rpc.js"; +import {readArguments} from "./arguments.js"; +import {readConfig} from "./config.js"; -var args = process.argv.slice(2); +const args = readArguments(process.argv.slice(2)) -const port = args[0] -const relay = args[1] -const ethRpcURI = args[2] -const serviceId = args[3] - -let errors = [] -if (!port) { - errors.push("Specify port") -} -if (!relay) { - errors.push("Specify Fluence peer address") -} -if (!ethRpcURI) { - errors.push("Specify uri to ethereum RPC") -} -if (!serviceId) { - errors.push("Specify id to ethereum Aqua service") -} - -if (errors.length > 0) { - console.log("Example: aqua-eth-gateway ") - errors.forEach((err) => console.log(err)) +if (args.errors.length > 0) { + console.log(args.help) + args.errors.forEach((err) => console.log(err)) process.exit(1) } +const config = readConfig(args.configPath) + console.log("Running server...") const route = "/" @@ -130,18 +88,21 @@ const server = new JSONRPCServer(); // initialize fluence client const fluence = new FluencePeer(); -await fluence.start({connectTo: relay}) +await fluence.start({connectTo: args.relay}) // handler for logger registerLogger(fluence, { log: s => { console.log("log: " + s) - } + }, + logCall: s => { + console.log("Call will be to : " + s) + }, }) -async function methodHandler(req, op) { - console.log(`Receiving request '${op}'`) - const result = await call(fluence, ethRpcURI, op, req.map((s) => JSON.stringify(s)), serviceId) +async function methodHandler(req, method) { + console.log(`Receiving request '${method}'`) + const result = await randomLoadBalancingEth(fluence, config.providers, method, req.map((s) => JSON.stringify(s)), args.serviceId) return JSON.parse(result.value) @@ -171,6 +132,6 @@ app.post(route, (req, res) => { }); }); -app.listen(port); +app.listen(args.port); -console.log("Server was started on port " + port) \ No newline at end of file +console.log("Server was started on port " + args.port) \ No newline at end of file