diff --git a/.circleci/config.yml b/.circleci/config.yml index 08adce5..611c2ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,7 +29,7 @@ jobs: paths: - ~/.cargo - ~/.rustup - key: trust-graph00-{{ checksum "./service/Cargo.lock" }}-{{ checksum "./Cargo.lock" }}-{{ checksum "./keypair/Cargo.lock" }} + key: trust-graph00-{{ checksum "./Cargo.lock" }}-{{ checksum "./keypair/Cargo.lock" }} workflows: diff --git a/Cargo.lock b/Cargo.lock index f64aae7..bd8c151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -755,7 +755,7 @@ dependencies = [ [[package]] name = "fluence-keypair" -version = "0.3.0" +version = "0.4.0" dependencies = [ "asn1_der", "bs58 0.3.1", @@ -2478,7 +2478,7 @@ dependencies = [ [[package]] name = "trust-graph" -version = "0.2.7" +version = "0.2.8" dependencies = [ "bs58 0.3.1", "derivative", diff --git a/Cargo.toml b/Cargo.toml index e15fcf6..8479ea4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trust-graph" -version = "0.2.7" +version = "0.2.8" authors = ["Fluence Labs"] edition = "2018" description = "trust graph" @@ -11,7 +11,7 @@ repository = "https://github.com/fluencelabs/trust-graph" libp2p-core = { package = "fluence-fork-libp2p-core", version = "0.27.2", features = ["secp256k1"] } serde = { version = "=1.0.118", features = ["derive"] } -fluence-keypair = { path = "./keypair", version = "0.3.0" } +fluence-keypair = { path = "./keypair", version = "0.4.0" } serde_json = "1.0.58" bs58 = "0.3.1" failure = "0.1.6" diff --git a/example/generated/export.ts b/example/generated/export.ts new file mode 100644 index 0000000..3084c64 --- /dev/null +++ b/example/generated/export.ts @@ -0,0 +1,811 @@ +/** + * + * This file is auto-generated. Do not edit manually: changes may be erased. + * Generated by Aqua compiler: https://github.com/fluencelabs/aqua/. + * If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues + * Aqua version: 0.3.1-228 + * + */ +import { Fluence, FluencePeer } from '@fluencelabs/fluence'; +import { + ResultCodes, + RequestFlow, + RequestFlowBuilder, + CallParams, +} from '@fluencelabs/fluence/dist/internal/compilerSupport/v1'; + + +// Services + + +// Functions + + export function verify_trust(node: string, trust: {expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}, issuer_peer_id: string, config?: {ttl?: number}) : Promise<{error:string;success:boolean}>; + export function verify_trust(peer: FluencePeer, node: string, trust: {expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}, issuer_peer_id: string, config?: {ttl?: number}) : Promise<{error:string;success:boolean}>; + export function verify_trust(...args: any) { + let peer: FluencePeer; + let node: any; +let trust: any; +let issuer_peer_id: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +trust = args[2]; +issuer_peer_id = args[3]; +config = args[4]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +trust = args[1]; +issuer_peer_id = args[2]; +config = args[3]; + } + + let request: RequestFlow; + const promise = new Promise<{error:string;success:boolean}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "trust") [] trust) + ) + (call %init_peer_id% ("getDataSrv" "issuer_peer_id") [] issuer_peer_id) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (seq + (call node ("peer" "timestamp_sec") [] timestamp_sec) + (call node ("trust-graph" "verify_trust") [trust issuer_peer_id timestamp_sec] result) + ) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'trust', () => {return trust;}); +h.on('getDataSrv', 'issuer_peer_id', () => {return issuer_peer_id;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for verify_trust'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + + export function issue_trust(node: string, issued_for_peer_id: string, expires_at_sec: number, issued_at_sec: number, trust_bytes: number[], config?: {ttl?: number}) : Promise<{error:string;success:boolean;trust:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}}>; + export function issue_trust(peer: FluencePeer, node: string, issued_for_peer_id: string, expires_at_sec: number, issued_at_sec: number, trust_bytes: number[], config?: {ttl?: number}) : Promise<{error:string;success:boolean;trust:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}}>; + export function issue_trust(...args: any) { + let peer: FluencePeer; + let node: any; +let issued_for_peer_id: any; +let expires_at_sec: any; +let issued_at_sec: any; +let trust_bytes: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +issued_for_peer_id = args[2]; +expires_at_sec = args[3]; +issued_at_sec = args[4]; +trust_bytes = args[5]; +config = args[6]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +issued_for_peer_id = args[1]; +expires_at_sec = args[2]; +issued_at_sec = args[3]; +trust_bytes = args[4]; +config = args[5]; + } + + let request: RequestFlow; + const promise = new Promise<{error:string;success:boolean;trust:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "issued_for_peer_id") [] issued_for_peer_id) + ) + (call %init_peer_id% ("getDataSrv" "expires_at_sec") [] expires_at_sec) + ) + (call %init_peer_id% ("getDataSrv" "issued_at_sec") [] issued_at_sec) + ) + (call %init_peer_id% ("getDataSrv" "trust_bytes") [] trust_bytes) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call node ("trust-graph" "issue_trust") [issued_for_peer_id expires_at_sec issued_at_sec trust_bytes] result) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'issued_for_peer_id', () => {return issued_for_peer_id;}); +h.on('getDataSrv', 'expires_at_sec', () => {return expires_at_sec;}); +h.on('getDataSrv', 'issued_at_sec', () => {return issued_at_sec;}); +h.on('getDataSrv', 'trust_bytes', () => {return trust_bytes;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for issue_trust'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + + export function insert_cert(node: string, certificate: {chain:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}[]}, config?: {ttl?: number}) : Promise<{error:string;success:boolean}>; + export function insert_cert(peer: FluencePeer, node: string, certificate: {chain:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}[]}, config?: {ttl?: number}) : Promise<{error:string;success:boolean}>; + export function insert_cert(...args: any) { + let peer: FluencePeer; + let node: any; +let certificate: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +certificate = args[2]; +config = args[3]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +certificate = args[1]; +config = args[2]; + } + + let request: RequestFlow; + const promise = new Promise<{error:string;success:boolean}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "certificate") [] certificate) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (seq + (call node ("peer" "timestamp_sec") [] timestamp_sec) + (call node ("trust-graph" "insert_cert") [certificate timestamp_sec] result) + ) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'certificate', () => {return certificate;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for insert_cert'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + + export function get_all_certs(node: string, issued_for: string, config?: {ttl?: number}) : Promise<{certificates:{chain:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}[]}[];error:string;success:boolean}>; + export function get_all_certs(peer: FluencePeer, node: string, issued_for: string, config?: {ttl?: number}) : Promise<{certificates:{chain:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}[]}[];error:string;success:boolean}>; + export function get_all_certs(...args: any) { + let peer: FluencePeer; + let node: any; +let issued_for: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +issued_for = args[2]; +config = args[3]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +issued_for = args[1]; +config = args[2]; + } + + let request: RequestFlow; + const promise = new Promise<{certificates:{chain:{expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}[]}[];error:string;success:boolean}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "issued_for") [] issued_for) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (seq + (call node ("peer" "timestamp_sec") [] timestamp_sec) + (call node ("trust-graph" "get_all_certs") [issued_for timestamp_sec] result) + ) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'issued_for', () => {return issued_for;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for get_all_certs'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + + export function add_trust(node: string, trust: {expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}, issuer_peer_id: string, config?: {ttl?: number}) : Promise<{error:string;success:boolean;weight:number}>; + export function add_trust(peer: FluencePeer, node: string, trust: {expires_at:number;issued_at:number;issued_for:string;sig_type:string;signature:string}, issuer_peer_id: string, config?: {ttl?: number}) : Promise<{error:string;success:boolean;weight:number}>; + export function add_trust(...args: any) { + let peer: FluencePeer; + let node: any; +let trust: any; +let issuer_peer_id: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +trust = args[2]; +issuer_peer_id = args[3]; +config = args[4]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +trust = args[1]; +issuer_peer_id = args[2]; +config = args[3]; + } + + let request: RequestFlow; + const promise = new Promise<{error:string;success:boolean;weight:number}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "trust") [] trust) + ) + (call %init_peer_id% ("getDataSrv" "issuer_peer_id") [] issuer_peer_id) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (seq + (call node ("peer" "timestamp_sec") [] timestamp_sec) + (call node ("trust-graph" "add_trust") [trust issuer_peer_id timestamp_sec] result) + ) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'trust', () => {return trust;}); +h.on('getDataSrv', 'issuer_peer_id', () => {return issuer_peer_id;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for add_trust'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + + export function add_root(node: string, peer_id: string, weight_factor: number, config?: {ttl?: number}) : Promise<{error:string;success:boolean}>; + export function add_root(peer: FluencePeer, node: string, peer_id: string, weight_factor: number, config?: {ttl?: number}) : Promise<{error:string;success:boolean}>; + export function add_root(...args: any) { + let peer: FluencePeer; + let node: any; +let peer_id: any; +let weight_factor: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +peer_id = args[2]; +weight_factor = args[3]; +config = args[4]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +peer_id = args[1]; +weight_factor = args[2]; +config = args[3]; + } + + let request: RequestFlow; + const promise = new Promise<{error:string;success:boolean}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "peer_id") [] peer_id) + ) + (call %init_peer_id% ("getDataSrv" "weight_factor") [] weight_factor) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call node ("trust-graph" "add_root") [peer_id weight_factor] result) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'peer_id', () => {return peer_id;}); +h.on('getDataSrv', 'weight_factor', () => {return weight_factor;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for add_root'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + + export function get_weight(node: string, peer_id: string, config?: {ttl?: number}) : Promise<{error:string;peer_id:string;success:boolean;weight:number}>; + export function get_weight(peer: FluencePeer, node: string, peer_id: string, config?: {ttl?: number}) : Promise<{error:string;peer_id:string;success:boolean;weight:number}>; + export function get_weight(...args: any) { + let peer: FluencePeer; + let node: any; +let peer_id: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +peer_id = args[2]; +config = args[3]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +peer_id = args[1]; +config = args[2]; + } + + let request: RequestFlow; + const promise = new Promise<{error:string;peer_id:string;success:boolean;weight:number}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "peer_id") [] peer_id) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (seq + (call node ("peer" "timestamp_sec") [] timestamp_sec) + (call node ("trust-graph" "get_weight") [peer_id timestamp_sec] result) + ) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'peer_id', () => {return peer_id;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for get_weight'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + + + + export function get_trust_bytes(node: string, issued_for_peer_id: string, expires_at_sec: number, issued_at_sec: number, config?: {ttl?: number}) : Promise<{error:string;result:number[];success:boolean}>; + export function get_trust_bytes(peer: FluencePeer, node: string, issued_for_peer_id: string, expires_at_sec: number, issued_at_sec: number, config?: {ttl?: number}) : Promise<{error:string;result:number[];success:boolean}>; + export function get_trust_bytes(...args: any) { + let peer: FluencePeer; + let node: any; +let issued_for_peer_id: any; +let expires_at_sec: any; +let issued_at_sec: any; + let config: any; + if (FluencePeer.isInstance(args[0])) { + peer = args[0]; + node = args[1]; +issued_for_peer_id = args[2]; +expires_at_sec = args[3]; +issued_at_sec = args[4]; +config = args[5]; + } else { + peer = Fluence.getPeer(); + node = args[0]; +issued_for_peer_id = args[1]; +expires_at_sec = args[2]; +issued_at_sec = args[3]; +config = args[4]; + } + + let request: RequestFlow; + const promise = new Promise<{error:string;result:number[];success:boolean}>((resolve, reject) => { + const r = new RequestFlowBuilder() + .disableInjections() + .withRawScript( + ` + (xor + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (seq + (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-) + (call %init_peer_id% ("getDataSrv" "node") [] node) + ) + (call %init_peer_id% ("getDataSrv" "issued_for_peer_id") [] issued_for_peer_id) + ) + (call %init_peer_id% ("getDataSrv" "expires_at_sec") [] expires_at_sec) + ) + (call %init_peer_id% ("getDataSrv" "issued_at_sec") [] issued_at_sec) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call node ("trust-graph" "get_trust_bytes") [issued_for_peer_id expires_at_sec issued_at_sec] result) + (seq + (call -relay- ("op" "noop") []) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1]) + ) + ) + ) + (call -relay- ("op" "noop") []) + ) + (xor + (call %init_peer_id% ("callbackSrv" "response") [result]) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2]) + ) + ) + (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3]) +) + + `, + ) + .configHandler((h) => { + h.on('getDataSrv', '-relay-', () => { + return peer.getStatus().relayPeerId; + }); + h.on('getDataSrv', 'node', () => {return node;}); +h.on('getDataSrv', 'issued_for_peer_id', () => {return issued_for_peer_id;}); +h.on('getDataSrv', 'expires_at_sec', () => {return expires_at_sec;}); +h.on('getDataSrv', 'issued_at_sec', () => {return issued_at_sec;}); + h.onEvent('callbackSrv', 'response', (args) => { + const [res] = args; + resolve(res); +}); + + h.onEvent('errorHandlingSrv', 'error', (args) => { + const [err] = args; + reject(err); + }); + }) + .handleScriptError(reject) + .handleTimeout(() => { + reject('Request timed out for get_trust_bytes'); + }) + if(config && config.ttl) { + r.withTTL(config.ttl) + } + request = r.build(); + }); + peer.internals.initiateFlow(request!); + return promise; +} + diff --git a/keypair/Cargo.toml b/keypair/Cargo.toml index 9deee80..3312288 100644 --- a/keypair/Cargo.toml +++ b/keypair/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fluence-keypair" -version = "0.3.0" +version = "0.4.0" authors = ["Fluence Labs"] edition = "2018" description = "identity" diff --git a/keypair/src/error.rs b/keypair/src/error.rs index 37e02a5..78c76d6 100644 --- a/keypair/src/error.rs +++ b/keypair/src/error.rs @@ -35,7 +35,7 @@ pub enum DecodingError { Ed25519( #[from] #[source] - ed25519_dalek::ed25519::Error + ed25519_dalek::ed25519::Error, ), #[error("Failed to decode with RSA")] Rsa, @@ -49,6 +49,8 @@ pub enum DecodingError { Base58DecodeError(#[source] bs58::decode::Error), #[error("Raw signature decoding failed: type {0} not supported")] RawSignatureUnsupportedType(String), + #[error("public key is not inlined in peer id: {0}")] + PublicKeyNotInlined(String), } /// An error during signing of a message. @@ -58,7 +60,7 @@ pub enum SigningError { Ed25519( #[from] #[source] - ed25519_dalek::ed25519::Error + ed25519_dalek::ed25519::Error, ), #[error("Failed to sign with RSA")] Rsa, @@ -66,6 +68,6 @@ pub enum SigningError { Secp256k1( #[from] #[source] - secp256k1::Error + secp256k1::Error, ), } diff --git a/keypair/src/key_pair.rs b/keypair/src/key_pair.rs index a6fb43b..f756d5a 100644 --- a/keypair/src/key_pair.rs +++ b/keypair/src/key_pair.rs @@ -20,15 +20,15 @@ //! A node's network identity keys. use crate::ed25519; +use crate::error::{DecodingError, Error, SigningError}; +use crate::public_key::PublicKey; #[cfg(not(target_arch = "wasm32"))] use crate::rsa; use crate::secp256k1; -use crate::public_key::PublicKey; use crate::signature::Signature; -use crate::error::{Error, DecodingError, SigningError}; -use std::str::FromStr; -use std::convert::TryFrom; use libp2p_core::PeerId; +use std::convert::TryFrom; +use std::str::FromStr; /// Identity keypair of a node. /// @@ -48,7 +48,6 @@ use libp2p_core::PeerId; /// ``` /// - pub enum KeyFormat { Ed25519, #[cfg(not(target_arch = "wasm32"))] @@ -66,7 +65,7 @@ impl FromStr for KeyFormat { "secp256k1" => Ok(KeyFormat::Secp256k1), #[cfg(not(target_arch = "wasm32"))] "rsa" => Ok(KeyFormat::Rsa), - _ => Err(Error::InvalidKeyFormat(s.to_string())) + _ => Err(Error::InvalidKeyFormat(s.to_string())), } } } @@ -80,7 +79,7 @@ impl TryFrom for KeyFormat { #[cfg(not(target_arch = "wasm32"))] 1 => Ok(KeyFormat::Rsa), 2 => Ok(KeyFormat::Secp256k1), - _ => Err(DecodingError::InvalidTypeByte) + _ => Err(DecodingError::InvalidTypeByte), } } } @@ -96,6 +95,16 @@ impl From for u8 { } } +impl From for String { + fn from(kf: KeyFormat) -> Self { + match kf { + KeyFormat::Ed25519 => "ed25519".to_string(), + #[cfg(not(target_arch = "wasm32"))] + KeyFormat::Rsa => "rsa".to_string(), + KeyFormat::Secp256k1 => "secp256k1".to_string(), + } + } +} #[derive(Clone)] pub enum KeyPair { /// An Ed25519 keypair. @@ -153,7 +162,9 @@ impl KeyPair { Ed25519(ref pair) => Ok(Signature::Ed25519(ed25519::Signature(pair.sign(msg)?))), #[cfg(not(target_arch = "wasm32"))] Rsa(ref pair) => Ok(Signature::Rsa(rsa::Signature(pair.sign(msg)?))), - Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature(pair.secret().sign(msg)?))) + Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature( + pair.secret().sign(msg)?, + ))), } } @@ -200,12 +211,12 @@ impl KeyPair { KeyFormat::Ed25519 => Ok(Ed25519(ed25519::Keypair::decode(&mut bytes)?)), KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())), #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported) + KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported), } } pub fn get_peer_id(&self) -> PeerId { - self.public().to_peer_id() + self.public().to_peer_id() } } @@ -217,23 +228,33 @@ impl From for KeyPair { Ed25519(kp) => KeyPair::Ed25519(ed25519::Keypair::decode(&mut kp.encode()).unwrap()), #[cfg(not(target_arch = "wasm32"))] // safety: these Keypair structures are identical - Rsa(kp) => KeyPair::Rsa(unsafe { std::mem::transmute::(kp) }), - Secp256k1(kp) => KeyPair::Secp256k1(secp256k1::Keypair::from(secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap())), + Rsa(kp) => KeyPair::Rsa(unsafe { + std::mem::transmute::(kp) + }), + Secp256k1(kp) => KeyPair::Secp256k1(secp256k1::Keypair::from( + secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(), + )), } } } impl From for libp2p_core::identity::Keypair { fn from(key: KeyPair) -> Self { - use KeyPair::*; - use libp2p_core::identity::Keypair; use libp2p_core::identity; + use libp2p_core::identity::Keypair; + use KeyPair::*; match key { - Ed25519(kp) => Keypair::Ed25519(identity::ed25519::Keypair::decode(kp.encode().to_vec().as_mut_slice()).unwrap()), + Ed25519(kp) => Keypair::Ed25519( + identity::ed25519::Keypair::decode(kp.encode().to_vec().as_mut_slice()).unwrap(), + ), #[cfg(not(target_arch = "wasm32"))] - Rsa(kp) => Keypair::Rsa(unsafe { std::mem::transmute::(kp) }), - Secp256k1(kp) => Keypair::Secp256k1(identity::secp256k1::Keypair::from(identity::secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap())), + Rsa(kp) => Keypair::Rsa(unsafe { + std::mem::transmute::(kp) + }), + Secp256k1(kp) => Keypair::Secp256k1(identity::secp256k1::Keypair::from( + identity::secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(), + )), } } } diff --git a/keypair/src/public_key.rs b/keypair/src/public_key.rs index cde4028..218c078 100644 --- a/keypair/src/public_key.rs +++ b/keypair/src/public_key.rs @@ -111,6 +111,17 @@ impl PublicKey { pub fn to_peer_id(&self) -> PeerId { PeerId::from_public_key(self.clone().into()) } + + pub fn get_key_format(&self) -> KeyFormat { + use PublicKey::*; + + match self { + Ed25519(_) => KeyFormat::Ed25519, + #[cfg(not(target_arch = "wasm32"))] + Rsa(_) => KeyFormat::Rsa, + Secp256k1(_) => KeyFormat::Secp256k1, + } + } } impl From for PublicKey { @@ -149,14 +160,15 @@ impl From for libp2p_core::identity::PublicKey { } } -pub fn peer_id_to_fluence_pk(peer_id: libp2p_core::PeerId) -> eyre::Result { - Ok(peer_id - .as_public_key() - .ok_or(eyre::eyre!( - "public key is not inlined in peer id: {}", - peer_id - ))? - .into()) +impl TryFrom for PublicKey { + type Error = DecodingError; + + fn try_from(peer_id: libp2p_core::PeerId) -> Result { + Ok(peer_id + .as_public_key() + .ok_or(DecodingError::PublicKeyNotInlined(peer_id.to_base58()))? + .into()) + } } #[cfg(test)] @@ -179,4 +191,15 @@ mod tests { let encoded_pk = pk.encode(); assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap()); } + + #[test] + fn public_key_peer_id_conversions() { + let kp = KeyPair::generate_secp256k1(); + let fluence_pk = kp.public(); + let libp2p_pk: libp2p_core::PublicKey = fluence_pk.clone().into(); + let peer_id = PeerId::from_public_key(libp2p_pk); + let fluence_pk_converted = PublicKey::try_from(peer_id).unwrap(); + + assert_eq!(fluence_pk, fluence_pk_converted); + } } diff --git a/keypair/src/signature.rs b/keypair/src/signature.rs index bb05da8..f794c8b 100644 --- a/keypair/src/signature.rs +++ b/keypair/src/signature.rs @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -use crate::{ed25519, PublicKey}; -use crate::secp256k1; +use crate::ed25519; +use crate::error::DecodingError; +use crate::key_pair::KeyFormat; #[cfg(not(target_arch = "wasm32"))] use crate::rsa; -use crate::error::DecodingError; +use crate::secp256k1; use serde::{Deserialize, Serialize}; -use crate::key_pair::KeyFormat; use std::convert::TryFrom; #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] @@ -32,7 +32,7 @@ pub enum Signature { pub struct RawSignature { pub bytes: Vec, - pub sig_type: String, + pub sig_type: KeyFormat, } impl Signature { @@ -42,7 +42,7 @@ impl Signature { Ed25519(_) => KeyFormat::Ed25519.into(), #[cfg(not(target_arch = "wasm32"))] Rsa(_) => KeyFormat::Rsa.into(), - Secp256k1(_) => KeyFormat::Secp256k1.into() + Secp256k1(_) => KeyFormat::Secp256k1.into(), } } @@ -68,7 +68,9 @@ impl Signature { KeyFormat::Ed25519 => Ok(Signature::Ed25519(ed25519::Signature(bytes[1..].to_vec()))), #[cfg(not(target_arch = "wasm32"))] KeyFormat::Rsa => Ok(Signature::Rsa(rsa::Signature(bytes[1..].to_vec()))), - KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature(bytes[1..].to_vec()))), + KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature( + bytes[1..].to_vec(), + ))), } } @@ -83,38 +85,30 @@ impl Signature { } } - pub fn get_signature_type(&self) -> String { + pub fn get_signature_type(&self) -> KeyFormat { use Signature::*; match self { - Ed25519(_) => "Ed25519".to_string(), + Ed25519(_) => KeyFormat::Ed25519, #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => "RSA".to_string(), - Secp256k1(_) => "Secp256k1".to_string(), + Rsa(_) => KeyFormat::Rsa, + Secp256k1(_) => KeyFormat::Secp256k1, } } pub fn get_raw_signature(&self) -> RawSignature { - RawSignature { bytes: self.to_vec().clone().to_vec(), sig_type: self.get_signature_type() } - } - - pub fn from_raw_signature(raw_signature: RawSignature) -> Result { - match raw_signature.sig_type.as_str() { - "Ed25519" => Ok(Signature::Ed25519(crate::ed25519::Signature(raw_signature.bytes))), - #[cfg(not(target_arch = "wasm32"))] - "RSA" => Ok(Signature::Rsa(crate::rsa::Signature(raw_signature.bytes))), - "Secp256k1" => Ok(Signature::Secp256k1(crate::secp256k1::Signature(raw_signature.bytes))), - _ => Err(DecodingError::RawSignatureUnsupportedType(raw_signature.sig_type)), + RawSignature { + bytes: self.to_vec().clone().to_vec(), + sig_type: self.get_signature_type(), } } - pub fn from_bytes_with_public_key(pk: &PublicKey, bytes: Vec) -> Self { - use PublicKey::*; - match pk { - Ed25519(_) => Signature::Ed25519(ed25519::Signature(bytes)), + pub fn from_bytes(key_format: KeyFormat, bytes: Vec) -> Self { + match key_format { + KeyFormat::Ed25519 => Signature::Ed25519(ed25519::Signature(bytes)), #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => Signature::Rsa(rsa::Signature(bytes)), - Secp256k1(_) => Signature::Secp256k1(secp256k1::Signature(bytes)) + KeyFormat::Rsa => Signature::Rsa(rsa::Signature(bytes)), + KeyFormat::Secp256k1 => Signature::Secp256k1(secp256k1::Signature(bytes)), } } } @@ -131,8 +125,14 @@ mod tests { #[cfg(not(target_arch = "wasm32"))] let rsa_sig = Signature::Rsa(crate::rsa::Signature(bytes.clone())); - assert_eq!(Signature::decode(ed25519_sig.encode()).unwrap(), ed25519_sig); - assert_eq!(Signature::decode(secp256k1_sig.encode()).unwrap(), secp256k1_sig); + assert_eq!( + Signature::decode(ed25519_sig.encode()).unwrap(), + ed25519_sig + ); + assert_eq!( + Signature::decode(secp256k1_sig.encode()).unwrap(), + secp256k1_sig + ); #[cfg(not(target_arch = "wasm32"))] assert_eq!(Signature::decode(rsa_sig.encode()).unwrap(), rsa_sig); } diff --git a/service/Cargo.toml b/service/Cargo.toml index 0398374..e005acc 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -12,7 +12,7 @@ path = "src/main.rs" [dependencies] trust-graph = { version = "0.2.6", path = "../." } -fluence-keypair = { version = "0.3.0", path = "../keypair" } +fluence-keypair = { version = "0.4.0", path = "../keypair" } marine-rs-sdk = { version = "0.6.11", features = ["logger"] } marine-sqlite-connector = "0.5.1" diff --git a/service/src/dto.rs b/service/src/dto.rs index 6e9fe40..111c562 100644 --- a/service/src/dto.rs +++ b/service/src/dto.rs @@ -1,8 +1,7 @@ use crate::dto::DtoConversionError::PeerIdDecodeError; use fluence_keypair::error::DecodingError; -use fluence_keypair::public_key::peer_id_to_fluence_pk; use fluence_keypair::signature::RawSignature; -use fluence_keypair::Signature; +use fluence_keypair::{KeyFormat, PublicKey, Signature}; use libp2p_core::PeerId; use marine_rs_sdk::marine; use std::convert::TryFrom; @@ -26,6 +25,12 @@ pub enum DtoConversionError { ), #[error("Cannot decode peer id from string: {0}")] PeerIdDecodeError(String), + #[error("{0}")] + InvalidKeyFormat( + #[from] + #[source] + fluence_keypair::error::Error, + ), } #[marine] @@ -73,15 +78,12 @@ impl TryFrom for trust_graph::Trust { type Error = DtoConversionError; fn try_from(t: Trust) -> Result { - let issued_for = peer_id_to_fluence_pk( + let issued_for = PublicKey::try_from( PeerId::from_str(&t.issued_for).map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?, ) .map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?; let signature = bs58::decode(&t.signature).into_vec()?; - let signature = Signature::from_raw_signature(RawSignature { - bytes: signature, - sig_type: t.sig_type, - })?; + let signature = Signature::from_bytes(KeyFormat::from_str(&t.sig_type)?, signature); let expires_at = Duration::from_secs(t.expires_at); let issued_at = Duration::from_secs(t.issued_at); return Ok(trust_graph::Trust { @@ -104,7 +106,7 @@ impl From for Trust { issued_for, expires_at, signature, - sig_type: raw_signature.sig_type, + sig_type: raw_signature.sig_type.into(), issued_at, }; } @@ -129,20 +131,17 @@ impl TryFrom for trust_graph::Revoke { type Error = DtoConversionError; fn try_from(r: Revoke) -> Result { - let revoked_pk = peer_id_to_fluence_pk( + let revoked_pk = PublicKey::try_from( PeerId::from_str(&r.revoked_peer_id) .map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?, ) .map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?; - let revoked_by_pk = peer_id_to_fluence_pk( + let revoked_by_pk = PublicKey::try_from( PeerId::from_str(&r.revoked_by).map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?, ) .map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?; let signature = bs58::decode(&r.signature).into_vec()?; - let signature = Signature::from_raw_signature(RawSignature { - bytes: signature, - sig_type: r.sig_type, - })?; + let signature = Signature::from_bytes(KeyFormat::from_str(&r.sig_type)?, signature); let revoked_at = Duration::from_secs(r.revoked_at); return Ok(trust_graph::Revoke { pk: revoked_pk, @@ -164,7 +163,7 @@ impl From for Revoke { revoked_peer_id, revoked_at, signature, - sig_type: raw_signature.sig_type, + sig_type: raw_signature.sig_type.into(), revoked_by, }; } diff --git a/service/src/service_impl.rs b/service/src/service_impl.rs index c40f47a..1919786 100644 --- a/service/src/service_impl.rs +++ b/service/src/service_impl.rs @@ -2,12 +2,10 @@ use crate::dto::{Certificate, DtoConversionError, Revoke, Trust}; use crate::service_impl::ServiceError::InvalidTimestampTetraplet; use crate::storage_impl::get_data; use fluence_keypair::error::DecodingError; -use fluence_keypair::public_key::peer_id_to_fluence_pk; use fluence_keypair::{PublicKey, Signature}; use libp2p_core::PeerId; use marine_rs_sdk::CallParameters; -use std::convert::{Into, TryInto}; -use std::iter::Rev; +use std::convert::{Into, TryFrom, TryInto}; use std::str::FromStr; use std::time::Duration; use thiserror::Error as ThisError; @@ -81,8 +79,11 @@ fn parse_peer_id(peer_id: String) -> Result { } fn extract_public_key(peer_id: String) -> Result { - peer_id_to_fluence_pk(parse_peer_id(peer_id)?) - .map_err(|e| ServiceError::PublicKeyExtractionError(e.to_string())) + PublicKey::try_from( + parse_peer_id(peer_id) + .map_err(|e| ServiceError::PublicKeyExtractionError(e.to_string()))?, + ) + .map_err(ServiceError::PublicKeyDecodeError) } pub fn get_weight_impl(peer_id: String, timestamp_sec: u64) -> Result { @@ -155,7 +156,7 @@ pub fn issue_trust_impl( let public_key = extract_public_key(peer_id)?; let expires_at_sec = Duration::from_secs(expires_at_sec); let issued_at_sec = Duration::from_secs(issued_at_sec); - let signature = Signature::from_bytes_with_public_key(&public_key, trust_bytes); + let signature = Signature::from_bytes(public_key.get_key_format(), trust_bytes); Ok(Trust::from(trust_graph::Trust::new( public_key, expires_at_sec, @@ -222,7 +223,7 @@ pub fn issue_revocation_impl( let revoked_by_pk = extract_public_key(revoked_by_peer_id)?; let revoked_at = Duration::from_secs(revoked_at_sec); - let signature = Signature::from_bytes_with_public_key(&revoked_by_pk, signature_bytes); + let signature = Signature::from_bytes(revoked_by_pk.get_key_format(), signature_bytes); Ok(trust_graph::Revoke::new(revoked_pk, revoked_by_pk, revoked_at, signature).into()) } diff --git a/src/trust.rs b/src/trust.rs index cbe91b7..9d896aa 100644 --- a/src/trust.rs +++ b/src/trust.rs @@ -14,7 +14,9 @@ * limitations under the License. */ -use crate::trust::TrustError::{Base58DecodeError, DecodePublicKeyError, ParseError, SignatureError, DecodeErrorInvalidSize}; +use crate::trust::TrustError::{ + Base58DecodeError, DecodeErrorInvalidSize, DecodePublicKeyError, ParseError, SignatureError, +}; use derivative::Derivative; use fluence_keypair::key_pair::KeyPair; use fluence_keypair::public_key::PublicKey;