mirror of
https://github.com/fluencelabs/trust-graph
synced 2025-07-05 09:31:38 +00:00
Compare commits
3 Commits
v0.1.5-hl-
...
v0.2.0
Author | SHA1 | Date | |
---|---|---|---|
048406aa02 | |||
b76954782b | |||
c2f63cb41e |
@ -16,19 +16,19 @@ jobs:
|
|||||||
sudo bash .github/download_marine.sh
|
sudo bash .github/download_marine.sh
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- trust-graph00-{{ checksum "./Cargo.lock" }}-{{ checksum "./keypair/Cargo.lock" }}
|
- trust-graph00-{{ checksum "./Cargo.lock" }}
|
||||||
- run: |
|
- run: |
|
||||||
rustup target add wasm32-wasi
|
rustup target add wasm32-wasi
|
||||||
cargo test --no-fail-fast --release --all-features --
|
cargo test --no-fail-fast --release --all-features --
|
||||||
cd ./service
|
cd ./service
|
||||||
./build.sh
|
./build.sh
|
||||||
mkdir data
|
mkdir -p data
|
||||||
cargo test --no-fail-fast --release --all-features -- --test-threads=1
|
cargo test --no-fail-fast --release --all-features -- --test-threads=1
|
||||||
- save_cache:
|
- save_cache:
|
||||||
paths:
|
paths:
|
||||||
- ~/.cargo
|
- ~/.cargo
|
||||||
- ~/.rustup
|
- ~/.rustup
|
||||||
key: trust-graph00-{{ checksum "./Cargo.lock" }-{{ checksum "./service/Cargo.lock" }}}-{{ checksum "./keypair/Cargo.lock" }}
|
key: trust-graph00-{{ checksum "./Cargo.lock" }}
|
||||||
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -54,7 +54,7 @@ jobs:
|
|||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
profile: minimal
|
profile: minimal
|
||||||
toolchain: nightly-2021-09-01
|
toolchain: nightly-2022-01-16
|
||||||
target: wasm32-wasi
|
target: wasm32-wasi
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -16,3 +16,5 @@ example/src/generated/**
|
|||||||
example/generated/**
|
example/generated/**
|
||||||
admin/src/generated/**
|
admin/src/generated/**
|
||||||
admin/generated/**
|
admin/generated/**
|
||||||
|
|
||||||
|
target
|
||||||
|
598
Cargo.lock
generated
598
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -8,8 +8,8 @@ license = "Apache-2.0"
|
|||||||
repository = "https://github.com/fluencelabs/trust-graph"
|
repository = "https://github.com/fluencelabs/trust-graph"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libp2p-core = { package = "fluence-fork-libp2p-core", version = "0.27.2", features = ["secp256k1"] }
|
libp2p-core = { version = "0.31", default-features = false, features = [ "secp256k1" ] }
|
||||||
serde = { version = "=1.0.118", features = ["derive"] }
|
serde = { version = "1.0.118", features = ["derive"] }
|
||||||
|
|
||||||
fluence-keypair = { path = "./keypair", version = "0.5.0" }
|
fluence-keypair = { path = "./keypair", version = "0.5.0" }
|
||||||
serde_json = "1.0.58"
|
serde_json = "1.0.58"
|
||||||
|
37
README.md
37
README.md
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Trust Graph is network-wide peer relationship layer. It's designed to be used to prioritize resources and control permissions in open networks. Being a decentralized graph of relationships, basically a Web of Trust, Trust Graph is distributed among all network peers.
|
Trust Graph is network-wide peer relationship layer. It's designed to be used to prioritize resources and control permissions in open networks. Being a decentralized graph of relationships, basically a Web of Trust, Trust Graph is distributed among all network peers.
|
||||||
|
|
||||||
Specifically, Trust Graph is used to prioritize connections from known peers to counteract Sybil attacks while still keeping network open by reserving resources for unknown peers.
|
Specifically, Trust Graph is used is used to prioritize connections from known peers to counteract Sybil attacks while still keeping network open by reserving resources for unknown peers.
|
||||||
|
|
||||||
At the same time, Trust Graph can be used at the application level in various ways such as prioritization of service execution on authorized peers or to define an interconnected subnetwork among peers of a single protocol.
|
At the same time, Trust Graph can be used at the application level in various ways such as prioritization of service execution on authorized peers or to define an interconnected subnetwork among peers of a single protocol.
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ See [example](./example):
|
|||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
High-level API is defined in the [trust-graph-api.aqua](./aqua/trust-graph-api.aqua) module.
|
Low-level API is defined in the [trust-graph-api.aqua](./aqua/trust-graph-api.aqua) module.
|
||||||
|
|
||||||
## Directory structure
|
## Directory structure
|
||||||
|
|
||||||
@ -22,9 +22,9 @@ High-level API is defined in the [trust-graph-api.aqua](./aqua/trust-graph-api.a
|
|||||||
|
|
||||||
- [`keypair`](./keypair) directory is an abstracted cryptographical layer (key pairs, public keys, signatures, etc.)
|
- [`keypair`](./keypair) directory is an abstracted cryptographical layer (key pairs, public keys, signatures, etc.)
|
||||||
|
|
||||||
- [`service`](./service) is a package that provides `marine` API and could be compiled to a Wasm file. It is uses `SQLite` as storage
|
- [`service`](./service) is a package that provides `marine` API and could be compiled to a Wasm file. It is uses `SQLite` as storage.
|
||||||
|
|
||||||
- [`example`](./example) is a `js` script that shows how to use Trust Graph to label peers
|
- [`example`](./example) is a `js` script that shows how to issue, sign trusts/revocations, export certificates and distinguish Fluence nodes
|
||||||
|
|
||||||
- [`builtin-package`](./builtin-package) contains blueprint, configs and scripts for generation builtin package locally or via CI
|
- [`builtin-package`](./builtin-package) contains blueprint, configs and scripts for generation builtin package locally or via CI
|
||||||
|
|
||||||
@ -35,32 +35,3 @@ High-level API is defined in the [trust-graph-api.aqua](./aqua/trust-graph-api.a
|
|||||||
* [Aqua Book](https://fluence.dev/aqua-book/)
|
* [Aqua Book](https://fluence.dev/aqua-book/)
|
||||||
* [Aqua Playground](https://github.com/fluencelabs/aqua-playground)
|
* [Aqua Playground](https://github.com/fluencelabs/aqua-playground)
|
||||||
* [Aqua repo](https://github.com/fluencelabs/aqua)
|
* [Aqua repo](https://github.com/fluencelabs/aqua)
|
||||||
|
|
||||||
## How to use in Aqua
|
|
||||||
|
|
||||||
```
|
|
||||||
import "@fluencelabs/trust-graph/trust-graph-api.aqua"
|
|
||||||
import "@fluencelabs/trust-graph/trust-graph.aqua"
|
|
||||||
|
|
||||||
func my_function(peer_id: string) -> u32:
|
|
||||||
on HOST_PEER_ID:
|
|
||||||
result <- get_weight(peer_id)
|
|
||||||
<- result
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to use is js
|
|
||||||
1. Add the following to your dependencies
|
|
||||||
- `@fluencelabs/trust-graph`
|
|
||||||
- `@fluencelabs/aqua`
|
|
||||||
- `@fluencelabs/aqua-lib`
|
|
||||||
- `@fluencelabs/fluence`
|
|
||||||
- `@fluencelabs/fluence-network-environment`
|
|
||||||
|
|
||||||
2. Import dependencies
|
|
||||||
```typescript
|
|
||||||
import * as tg from "./generated/export";
|
|
||||||
import { Fluence, KeyPair } from "@fluencelabs/fluence";
|
|
||||||
import { krasnodar, Node } from "@fluencelabs/fluence-network-environment";
|
|
||||||
```
|
|
||||||
3. Add root and issue root trust.
|
|
||||||
4. For now, trusts/revocations can only be signed by client's private key.
|
|
@ -10,5 +10,3 @@
|
|||||||
all Fluence Labs relations. Trust from issuer key to any peer id means that this peer is official Fluence Labs peer.
|
all Fluence Labs relations. Trust from issuer key to any peer id means that this peer is official Fluence Labs peer.
|
||||||
isFluencePeer method from [trust-graph-api.aqua](./aqua/trust-graph-api.aqua) module checks these relations. You can build your own
|
isFluencePeer method from [trust-graph-api.aqua](./aqua/trust-graph-api.aqua) module checks these relations. You can build your own
|
||||||
structure of peers similarly.
|
structure of peers similarly.
|
||||||
|
|
||||||
`example_secret_key.ed25519` publicly available and used for test purposes.
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import "@fluencelabs/trust-graph/trust-graph.aqua"
|
import get_trust_bytes, issue_trust from "../../aqua/trust-graph-api.aqua"
|
||||||
export get_trust_bytes, issue_trust
|
export get_trust_bytes, issue_trust
|
||||||
|
|
||||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||||
@ -7,13 +7,3 @@ func timestamp_sec(node: string) -> u64:
|
|||||||
on node:
|
on node:
|
||||||
result <- Peer.timestamp_sec()
|
result <- Peer.timestamp_sec()
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
func get_trust_bytes(node: string, issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64) -> GetTrustBytesResult:
|
|
||||||
on node:
|
|
||||||
result <- TrustGraph.get_trust_bytes(issued_for_peer_id, expires_at_sec, issued_at_sec)
|
|
||||||
<- result
|
|
||||||
|
|
||||||
func issue_trust(node: string, issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64, trust_bytes: []u8) ->IssueTrustResult:
|
|
||||||
on node:
|
|
||||||
result <- TrustGraph.issue_trust(issued_for_peer_id, expires_at_sec, issued_at_sec, trust_bytes)
|
|
||||||
<- result
|
|
||||||
|
@ -49,29 +49,24 @@ async function main(environment: Node[]) {
|
|||||||
Fluence.getStatus().peerId,
|
Fluence.getStatus().peerId,
|
||||||
Fluence.getStatus().relayPeerId
|
Fluence.getStatus().relayPeerId
|
||||||
);
|
);
|
||||||
|
|
||||||
let root_sk_b58 = fs.readFileSync("./root_secret_key.ed25519").toString();
|
let root_sk_b58 = fs.readFileSync("./root_secret_key.ed25519").toString();
|
||||||
let issuer_sk_b58 = fs.readFileSync("./issuer_secret_key.ed25519").toString();
|
let issuer_sk_b58 = fs.readFileSync("./issuer_secret_key.ed25519").toString();
|
||||||
let example_sk_b58 = fs.readFileSync("../example_secret_key.ed25519").toString();
|
|
||||||
let root_kp = await KeyPair.fromEd25519SK(bs58.decode(root_sk_b58));
|
let root_kp = await KeyPair.fromEd25519SK(bs58.decode(root_sk_b58));
|
||||||
let issuer_kp = await KeyPair.fromEd25519SK(bs58.decode(issuer_sk_b58));
|
let issuer_kp = await KeyPair.fromEd25519SK(bs58.decode(issuer_sk_b58));
|
||||||
let example_kp = await KeyPair.fromEd25519SK(bs58.decode(example_sk_b58));
|
|
||||||
console.log("Root private key: %s", root_sk_b58);
|
console.log("Root private key: %s", root_sk_b58);
|
||||||
console.log("Root peer id: %s", root_kp.Libp2pPeerId.toB58String());
|
console.log("Root peer id: %s", root_kp.Libp2pPeerId.toB58String());
|
||||||
console.log("Issuer private key: %s", issuer_sk_b58);
|
console.log("Issuer private key: %s", issuer_sk_b58);
|
||||||
|
|
||||||
let cur_time = await timestamp_sec(node);
|
let cur_time = await timestamp_sec(node);
|
||||||
let expires_at = cur_time + 60 * 60 * 24 * 365;
|
let expires_at = cur_time + 60 * 60 * 24 * 365;
|
||||||
let certificates = [];
|
|
||||||
let common_chain = [] as any;
|
let common_chain = [] as any;
|
||||||
// self-signed root trust
|
// self-signed root trust
|
||||||
common_chain.push(await issue_trust_helper(node, root_kp, root_kp.Libp2pPeerId.toB58String(), root_kp.Libp2pPeerId.toB58String(), expires_at, cur_time));
|
common_chain.push(await issue_trust_helper(node, root_kp, root_kp.Libp2pPeerId.toB58String(), root_kp.Libp2pPeerId.toB58String(), expires_at, cur_time));
|
||||||
// from root to issuer
|
// from root to issuer
|
||||||
common_chain.push(await issue_trust_helper(node, root_kp, root_kp.Libp2pPeerId.toB58String(), issuer_kp.Libp2pPeerId.toB58String(), expires_at, cur_time));
|
common_chain.push(await issue_trust_helper(node, root_kp, root_kp.Libp2pPeerId.toB58String(), issuer_kp.Libp2pPeerId.toB58String(), expires_at, cur_time));
|
||||||
// from root to example
|
|
||||||
let trust = await issue_trust_helper(node, root_kp, root_kp.Libp2pPeerId.toB58String(), example_kp.Libp2pPeerId.toB58String(), expires_at, cur_time);
|
|
||||||
let cert = {chain: [...common_chain, trust]};
|
|
||||||
certificates.push(cert);
|
|
||||||
|
|
||||||
|
let certificates = [];
|
||||||
for (let i = 0; i < krasnodar.length; i++) {
|
for (let i = 0; i < krasnodar.length; i++) {
|
||||||
// from issuer to node
|
// from issuer to node
|
||||||
let trust = await issue_trust_helper(node, issuer_kp, issuer_kp.Libp2pPeerId.toB58String(), krasnodar[i].peerId, expires_at, cur_time);
|
let trust = await issue_trust_helper(node, issuer_kp, issuer_kp.Libp2pPeerId.toB58String(), krasnodar[i].peerId, expires_at, cur_time);
|
||||||
|
5218
admin/package-lock.json
generated
5218
admin/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,9 +13,9 @@
|
|||||||
"author": "Fluence Labs",
|
"author": "Fluence Labs",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluencelabs/aqua": "^0.5.2-257",
|
"@fluencelabs/aqua": "0.5.0-246",
|
||||||
"@fluencelabs/aqua-lib": "^0.3.2",
|
"@fluencelabs/aqua-lib": "0.2.1",
|
||||||
"@fluencelabs/fluence": "^0.18.0",
|
"@fluencelabs/fluence": "0.15.0",
|
||||||
"@fluencelabs/fluence-network-environment": "^1.0.10",
|
"@fluencelabs/fluence-network-environment": "^1.0.10",
|
||||||
"@fluencelabs/trust-graph": "file:../aqua",
|
"@fluencelabs/trust-graph": "file:../aqua",
|
||||||
"bs58": "^4.0.1"
|
"bs58": "^4.0.1"
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import "trust-graph.aqua"
|
|
||||||
|
|
||||||
-- helpers for isFluencePeer
|
|
||||||
service TrustOp("op"):
|
|
||||||
array_length(a: []Trust) -> u32
|
|
||||||
|
|
||||||
service BoolOp("op"):
|
|
||||||
array_length(a: []bool) -> u32
|
|
3066
aqua/package-lock.json
generated
3066
aqua/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@fluencelabs/trust-graph",
|
"name": "@fluencelabs/trust-graph",
|
||||||
"version": "0.2.2",
|
"version": "0.2.0",
|
||||||
"description": "Aqua Trust Graph API library",
|
"description": "Aqua Trust Graph API library",
|
||||||
"files": [
|
"files": [
|
||||||
"*.aqua"
|
"*.aqua"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluencelabs/aqua-lib": "^0.3.1"
|
"@fluencelabs/aqua-lib": "0.2.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"generate-aqua": "../service/build.sh",
|
"generate-aqua": "../service/build.sh",
|
||||||
@ -31,6 +31,6 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/fluencelabs/trust-graph#readme",
|
"homepage": "https://github.com/fluencelabs/trust-graph#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fluencelabs/aqua": "^0.5.2-257"
|
"@fluencelabs/aqua": "0.4.1-240"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,223 +1,100 @@
|
|||||||
import "trust-graph.aqua"
|
import "trust-graph.aqua"
|
||||||
import "misc.aqua"
|
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||||
import Sig, Peer from "@fluencelabs/aqua-lib/builtin.aqua"
|
|
||||||
|
|
||||||
alias PeerId: string
|
func get_trust_bytes(node: string, issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64) -> GetTrustBytesResult:
|
||||||
alias Error: string
|
on node:
|
||||||
|
result <- TrustGraph.get_trust_bytes(issued_for_peer_id, expires_at_sec, issued_at_sec)
|
||||||
-- Set peer_id as a root to TG instance on current node
|
|
||||||
-- Self-signed trust should be added in next call for correct behaviour
|
|
||||||
-- `max_chain_len` specifies maximum chain length after root trust,
|
|
||||||
-- if `max_chain_len` is zero there is no trusts except self-signed root trust in certificates for this root
|
|
||||||
func set_root(peer_id: PeerId, max_chain_len: u32) -> SetRootResult:
|
|
||||||
result <- TrustGraph.set_root(peer_id, max_chain_len)
|
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Create and sign trust with private key from 'sig_id' service
|
func issue_trust(node: string, issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64, trust_bytes: []u8) -> IssueTrustResult:
|
||||||
-- If `sig_id` is nil, default Sig service will be used with %init_peer_id% private key
|
on node:
|
||||||
func issue_trust(issued_for: PeerId, expires_at_sec: u64, sig_id: ?string) -> ?Trust, ?Error:
|
result <- TrustGraph.issue_trust(issued_for_peer_id, expires_at_sec, issued_at_sec, trust_bytes)
|
||||||
on HOST_PEER_ID:
|
|
||||||
issued_at_sec <- Peer.timestamp_sec()
|
|
||||||
bytes <- TrustGraph.get_trust_bytes(issued_for, expires_at_sec, issued_at_sec)
|
|
||||||
|
|
||||||
result: ?Trust
|
|
||||||
error: ?string
|
|
||||||
if bytes.success:
|
|
||||||
sig_service: ?string
|
|
||||||
if sig_id != nil:
|
|
||||||
sig_service <<- sig_id!
|
|
||||||
else:
|
|
||||||
sig_service <<- "sig"
|
|
||||||
|
|
||||||
Sig sig_service!
|
|
||||||
signature <- Sig.sign(bytes.result)
|
|
||||||
|
|
||||||
on HOST_PEER_ID:
|
|
||||||
issue_result <- TrustGraph.issue_trust(issued_for, expires_at_sec, issued_at_sec, signature)
|
|
||||||
if issue_result.success:
|
|
||||||
result <<- issue_result.trust
|
|
||||||
else:
|
|
||||||
error <<- issue_result.error
|
|
||||||
else:
|
|
||||||
error <<- bytes.error
|
|
||||||
<- result, error
|
|
||||||
|
|
||||||
-- Add trust to TG instance on current node
|
|
||||||
func import_trust(trust: Trust, issuer: PeerId) -> ?Error:
|
|
||||||
error: ?string
|
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
|
||||||
add_result <- TrustGraph.add_trust(trust, issuer, timestamp_sec)
|
|
||||||
if add_result.success != true:
|
|
||||||
error <<- add_result.error
|
|
||||||
<- error
|
|
||||||
|
|
||||||
-- Issue trust and add to TG instance on `node`
|
|
||||||
-- If `issuer` != %init_peer_id%, Sig service should be registered with issuer's peer id as a service id.
|
|
||||||
func add_trust(node: PeerId, issuer: PeerId, issued_for: PeerId, expires_at_sec: u64) -> ?Error:
|
|
||||||
sig_service: ?string
|
|
||||||
if issuer != %init_peer_id%:
|
|
||||||
sig_service <<- issuer
|
|
||||||
|
|
||||||
trust, issue_error <- issue_trust(issued_for, expires_at_sec, sig_service)
|
|
||||||
|
|
||||||
error: *?Error
|
|
||||||
if trust == nil:
|
|
||||||
error <<- issue_error
|
|
||||||
else:
|
|
||||||
on node:
|
|
||||||
error <- import_trust(trust!, issuer)
|
|
||||||
|
|
||||||
<- error!
|
|
||||||
|
|
||||||
-- Set `peer_id` as a root and add self-signed trust to TG instance on `node`
|
|
||||||
-- If `peer_id` != %init_peer_id%, Sig service should be registered with this peer id as a service id.
|
|
||||||
func add_root_trust(node: PeerId, peer_id: PeerId, max_chain_len: u32, expires_at_sec: u64) -> ?Error:
|
|
||||||
sig_service: ?string
|
|
||||||
if peer_id != %init_peer_id%:
|
|
||||||
sig_service <<- peer_id
|
|
||||||
|
|
||||||
trust, issue_error <- issue_trust(peer_id, expires_at_sec, sig_service)
|
|
||||||
|
|
||||||
error: *?Error
|
|
||||||
if trust == nil:
|
|
||||||
error <<- issue_error
|
|
||||||
else:
|
|
||||||
on node:
|
|
||||||
set_root_result <- set_root(peer_id, max_chain_len)
|
|
||||||
if set_root_result.success:
|
|
||||||
error <- import_trust(trust!, peer_id)
|
|
||||||
else:
|
|
||||||
-- converting string to ?string
|
|
||||||
tmp: *string
|
|
||||||
tmp <<- set_root_result.error
|
|
||||||
error <<- tmp
|
|
||||||
|
|
||||||
<- error!
|
|
||||||
|
|
||||||
-- Check signature and expiration time of trust
|
|
||||||
func verify_trust(trust: Trust, issuer: PeerId) -> VerifyTrustResult:
|
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
|
||||||
result <- TrustGraph.verify_trust(trust, issuer, timestamp_sec)
|
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Get the maximum weight of trust for one peer id
|
func verify_trust(node: string, trust: Trust, issuer_peer_id: string) -> VerifyTrustResult:
|
||||||
-- Trust has weight if there is at least 1 trust chain from one of the roots
|
on node:
|
||||||
func get_weight(peer_id: PeerId) -> WeightResult:
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
result <- TrustGraph.verify_trust(trust, issuer_peer_id, timestamp_sec)
|
||||||
result <- TrustGraph.get_weight(peer_id, timestamp_sec)
|
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Get maximum weight of trust among all chains which contain trust from `issuer`
|
func add_trust(node: string, trust: Trust, issuer_peer_id: string) -> AddTrustResult:
|
||||||
func get_weight_from(peer_id: PeerId, issuer: PeerId) -> WeightResult:
|
on node:
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
result <- TrustGraph.get_weight_from(peer_id, issuer, timestamp_sec)
|
result <- TrustGraph.add_trust(trust, issuer_peer_id, timestamp_sec)
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Create revocation signed by %init_peer_id%
|
func add_root(node: string, peer_id: string, weight_factor: u32) -> AddRootResult:
|
||||||
-- If `sig_id` is nil, default Sig service will be used with %init_peer_id% private key
|
on node:
|
||||||
func issue_revocation(revoked_by: PeerId, revoked: PeerId, sig_id: ?string) -> ?Revocation, ?Error:
|
result <- TrustGraph.add_root(peer_id, weight_factor)
|
||||||
on HOST_PEER_ID:
|
<- result
|
||||||
issued_at_sec <- Peer.timestamp_sec()
|
|
||||||
bytes <- TrustGraph.get_revocation_bytes(revoked, issued_at_sec)
|
|
||||||
|
|
||||||
result: ?Revocation
|
func get_weight(node: string, peer_id: string) -> WeightResult:
|
||||||
error: ?string
|
on node:
|
||||||
if bytes.success:
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
sig_service: ?string
|
result <- TrustGraph.get_weight(peer_id, timestamp_sec)
|
||||||
if sig_id != nil:
|
<- result
|
||||||
sig_service <<- sig_id!
|
|
||||||
else:
|
|
||||||
sig_service <<- "sig"
|
|
||||||
|
|
||||||
Sig sig_service!
|
func get_all_certs(node: string, issued_for: string) -> AllCertsResult:
|
||||||
signature <- Sig.sign(bytes.result)
|
on node:
|
||||||
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
|
result <- TrustGraph.get_all_certs(issued_for, timestamp_sec)
|
||||||
|
<- result
|
||||||
|
|
||||||
on HOST_PEER_ID:
|
func get_host_certs(node: string, issued_for: string) -> AllCertsResult:
|
||||||
issue_result <- TrustGraph.issue_revocation(revoked_by, revoked, issued_at_sec, signature)
|
on node:
|
||||||
if issue_result.success:
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
result <<- issue_result.revocation
|
result <- TrustGraph.get_host_certs(timestamp_sec)
|
||||||
else:
|
<- result
|
||||||
error <<- issue_result.error
|
|
||||||
else:
|
|
||||||
error <<- bytes.error
|
|
||||||
<- result, error
|
|
||||||
|
|
||||||
-- Import revocation to current node's TG instance
|
func get_host_certs_from(issuer: string) -> AllCertsResult:
|
||||||
func import_revocation(revocation: Revocation) -> ?Error:
|
|
||||||
error: ?string
|
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
|
||||||
add_result <- TrustGraph.revoke(revocation, timestamp_sec)
|
|
||||||
if add_result.success != true:
|
|
||||||
error <<- add_result.error
|
|
||||||
|
|
||||||
<- error
|
|
||||||
|
|
||||||
-- Revoke all certificates on `node` TG instance
|
|
||||||
-- which contain path from %init_peer_id% to `revoked_peer_id`
|
|
||||||
-- If `revoked_by` != %init_peer_id%, Sig service should be registered with this peer id as a service id.
|
|
||||||
func revoke(node: PeerId, revoked_by: PeerId, revoked: PeerId) -> ?Error:
|
|
||||||
sig_service: ?string
|
|
||||||
if revoked_by != %init_peer_id%:
|
|
||||||
sig_service <<- revoked_by
|
|
||||||
|
|
||||||
revocation, issue_error <- issue_revocation(revoked_by, revoked, sig_service)
|
|
||||||
|
|
||||||
error: *?string
|
|
||||||
if revocation == nil:
|
|
||||||
error <<- issue_error
|
|
||||||
else:
|
|
||||||
on node:
|
|
||||||
error <- import_revocation(revocation!)
|
|
||||||
|
|
||||||
<- error!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Return all certificates issued for current node which contains trust from `issuer`
|
|
||||||
func get_host_certs_from(issuer: PeerId) -> AllCertsResult:
|
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
result <- TrustGraph.get_host_certs_from(issuer, timestamp_sec)
|
result <- TrustGraph.get_host_certs_from(issuer, timestamp_sec)
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Return all certificates issued for given peer id
|
func insert_cert(node: string, certificate: Certificate) -> InsertResult:
|
||||||
func get_all_certs(issued_for: PeerId) -> AllCertsResult:
|
on node:
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
result <- TrustGraph.get_all_certs(issued_for, timestamp_sec)
|
result <- TrustGraph.insert_cert(certificate, timestamp_sec)
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Return all certificates issued for given peer id which contains trust from `issuer`
|
func get_revoke_bytes(node: string, revoked_peer_id: string, revoked_at: u64) -> GetRevokeBytesResult:
|
||||||
func get_all_certs_from(issued_for: PeerId, issuer: PeerId) -> AllCertsResult:
|
on node:
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
result <- TrustGraph.get_revoke_bytes(revoked_peer_id, revoked_at)
|
||||||
result <- TrustGraph.get_all_certs_from(issued_for, issuer, timestamp_sec)
|
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Return all certificates issued for current node
|
func issue_revocation(node: string, revoked_peer_id: string, revoked_by_peer_id: string, revoked_at_sec: u64, signature_bytes: []u8) -> IssueRevocationResult:
|
||||||
func get_host_certs() -> AllCertsResult:
|
on node:
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
result <- TrustGraph.issue_revocation(revoked_peer_id, revoked_by_peer_id, revoked_at_sec, signature_bytes)
|
||||||
result <- TrustGraph.get_host_certs(timestamp_sec)
|
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- Insert certificate to TG instance on current node
|
func revoke(node: string, revocation: Revocation) -> RevokeResult:
|
||||||
func insert_cert(certificate: Certificate) -> InsertResult:
|
on node:
|
||||||
timestamp_sec <- Peer.timestamp_sec()
|
timestamp_sec <- Peer.timestamp_sec()
|
||||||
result <- TrustGraph.insert_cert(certificate, timestamp_sec)
|
result <- TrustGraph.revoke(revocation, timestamp_sec)
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
-- returns `true` if current node is identified as official Fluence Labs peer
|
service TrustOp("op"):
|
||||||
-- returns `false` otherwise
|
array_length(a: []Trust) -> u32
|
||||||
func isFluencePeer() -> ?bool, ?Error:
|
|
||||||
certs_result <- get_host_certs_from("12D3KooWM45u7AQxsb4MuQJNYT3NWHHMLU7JTbBV66RTfF3KSzdR")
|
service BoolOp("op"):
|
||||||
result: ?bool
|
array_length(a: []bool) -> u32
|
||||||
error: ?string
|
|
||||||
if certs_result.success:
|
func isFluencePeer(node: string) -> bool:
|
||||||
for cert <- certs_result.certificates:
|
on node:
|
||||||
len <- TrustOp.array_length(cert.chain)
|
certs_result <- get_host_certs_from("12D3KooWM45u7AQxsb4MuQJNYT3NWHHMLU7JTbBV66RTfF3KSzdR")
|
||||||
if len == 3:
|
resultBox: *bool
|
||||||
if cert.chain!0.issued_for == "12D3KooWNbZKaPWRZ8wgjGvrxdJFz9Fq5uVwkR6ERV1f74HhPdyB":
|
if certs_result.success:
|
||||||
if cert.chain!1.issued_for == "12D3KooWM45u7AQxsb4MuQJNYT3NWHHMLU7JTbBV66RTfF3KSzdR":
|
for cert <- certs_result.certificates:
|
||||||
result <<- true
|
len <- TrustOp.array_length(cert.chain)
|
||||||
if result == nil:
|
if len == 3:
|
||||||
|
if cert.chain!0.issued_for == "12D3KooWNbZKaPWRZ8wgjGvrxdJFz9Fq5uVwkR6ERV1f74HhPdyB":
|
||||||
|
if cert.chain!1.issued_for == "12D3KooWM45u7AQxsb4MuQJNYT3NWHHMLU7JTbBV66RTfF3KSzdR":
|
||||||
|
resultBox <<- true
|
||||||
|
|
||||||
|
result_len <- BoolOp.array_length(resultBox)
|
||||||
|
result: *bool
|
||||||
|
if result_len == 0:
|
||||||
result <<- false
|
result <<- false
|
||||||
else:
|
else:
|
||||||
error <<- certs_result.error
|
result <<- true
|
||||||
<- result, error
|
<- result!
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
module TrustGraph declares *
|
module TrustGraph declares *
|
||||||
|
|
||||||
|
data AddRootResult:
|
||||||
|
success: bool
|
||||||
|
error: string
|
||||||
|
|
||||||
data AddTrustResult:
|
data AddTrustResult:
|
||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
@ -20,18 +24,6 @@ data AllCertsResult:
|
|||||||
certificates: []Certificate
|
certificates: []Certificate
|
||||||
error: string
|
error: string
|
||||||
|
|
||||||
data Revocation:
|
|
||||||
revoked_peer_id: string
|
|
||||||
revoked_at: u64
|
|
||||||
signature: string
|
|
||||||
sig_type: string
|
|
||||||
revoked_by: string
|
|
||||||
|
|
||||||
data ExportRevocationsResult:
|
|
||||||
success: bool
|
|
||||||
revocations: []Revocation
|
|
||||||
error: string
|
|
||||||
|
|
||||||
data GetRevokeBytesResult:
|
data GetRevokeBytesResult:
|
||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
@ -46,6 +38,13 @@ data InsertResult:
|
|||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
|
|
||||||
|
data Revocation:
|
||||||
|
revoked_peer_id: string
|
||||||
|
revoked_at: u64
|
||||||
|
signature: string
|
||||||
|
sig_type: string
|
||||||
|
revoked_by: string
|
||||||
|
|
||||||
data IssueRevocationResult:
|
data IssueRevocationResult:
|
||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
@ -60,10 +59,6 @@ data RevokeResult:
|
|||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
|
|
||||||
data SetRootResult:
|
|
||||||
success: bool
|
|
||||||
error: string
|
|
||||||
|
|
||||||
data VerifyTrustResult:
|
data VerifyTrustResult:
|
||||||
success: bool
|
success: bool
|
||||||
error: string
|
error: string
|
||||||
@ -75,20 +70,18 @@ data WeightResult:
|
|||||||
error: string
|
error: string
|
||||||
|
|
||||||
service TrustGraph("trust-graph"):
|
service TrustGraph("trust-graph"):
|
||||||
|
add_root(peer_id: string, weight_factor: u32) -> AddRootResult
|
||||||
add_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> AddTrustResult
|
add_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> AddTrustResult
|
||||||
export_revocations(issued_for: string) -> ExportRevocationsResult
|
|
||||||
get_all_certs(issued_for: string, timestamp_sec: u64) -> AllCertsResult
|
get_all_certs(issued_for: string, timestamp_sec: u64) -> AllCertsResult
|
||||||
get_all_certs_from(issued_for: string, issuer: string, timestamp_sec: u64) -> AllCertsResult
|
|
||||||
get_host_certs(timestamp_sec: u64) -> AllCertsResult
|
get_host_certs(timestamp_sec: u64) -> AllCertsResult
|
||||||
get_host_certs_from(issuer: string, timestamp_sec: u64) -> AllCertsResult
|
get_host_certs_from(issuer: string, timestamp_sec: u64) -> AllCertsResult
|
||||||
get_revocation_bytes(revoked_peer_id: string, revoked_at: u64) -> GetRevokeBytesResult
|
get_revoke_bytes(revoked_peer_id: string, revoked_at: u64) -> GetRevokeBytesResult
|
||||||
get_trust_bytes(issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64) -> GetTrustBytesResult
|
get_trust_bytes(issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64) -> GetTrustBytesResult
|
||||||
get_weight(peer_id: string, timestamp_sec: u64) -> WeightResult
|
get_weight(peer_id: string, timestamp_sec: u64) -> WeightResult
|
||||||
get_weight_from(peer_id: string, issuer: string, timestamp_sec: u64) -> WeightResult
|
get_weight_factor(max_chain_len: u32) -> u32
|
||||||
insert_cert(certificate: Certificate, timestamp_sec: u64) -> InsertResult
|
insert_cert(certificate: Certificate, timestamp_sec: u64) -> InsertResult
|
||||||
insert_cert_raw(certificate: string, timestamp_sec: u64) -> InsertResult
|
insert_cert_raw(certificate: string, timestamp_sec: u64) -> InsertResult
|
||||||
issue_revocation(revoked_by_peer_id: string, revoked_peer_id: string, revoked_at_sec: u64, signature_bytes: []u8) -> IssueRevocationResult
|
issue_revocation(revoked_peer_id: string, revoked_by_peer_id: string, revoked_at_sec: u64, signature_bytes: []u8) -> IssueRevocationResult
|
||||||
issue_trust(issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64, trust_bytes: []u8) -> IssueTrustResult
|
issue_trust(issued_for_peer_id: string, expires_at_sec: u64, issued_at_sec: u64, trust_bytes: []u8) -> IssueTrustResult
|
||||||
revoke(revoke: Revocation, timestamp_sec: u64) -> RevokeResult
|
revoke(revoke: Revocation, timestamp_sec: u64) -> RevokeResult
|
||||||
set_root(peer_id: string, max_chain_len: u32) -> SetRootResult
|
|
||||||
verify_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> VerifyTrustResult
|
verify_trust(trust: Trust, issuer_peer_id: string, timestamp_sec: u64) -> VerifyTrustResult
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
(seq
|
(seq
|
||||||
(seq
|
(seq
|
||||||
(call relay ("trust-graph" "set_root") ["12D3KooWNbZKaPWRZ8wgjGvrxdJFz9Fq5uVwkR6ERV1f74HhPdyB" 5] add_root_res)
|
(call relay ("trust-graph" "add_root") ["12D3KooWNbZKaPWRZ8wgjGvrxdJFz9Fq5uVwkR6ERV1f74HhPdyB" 2] add_root_res)
|
||||||
(xor
|
(xor
|
||||||
(match add_root_res.$.success! true
|
(match add_root_res.$.success! true
|
||||||
(null)
|
(null)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,10 +1,23 @@
|
|||||||
## Description
|
# Run example locally
|
||||||
This example shows how to use Trust Graph to label peers. There are some `trusted_computation` which can only be executed
|
|
||||||
on labeled peer. The label is determined by the presence of certificate from `%init_peer_id` to this peer.
|
|
||||||
|
|
||||||
## Run example locally
|
|
||||||
1. Go to `local-network`
|
1. Go to `local-network`
|
||||||
2. Run `docker compose up -d` to start Fluence node
|
2. Run `docker compose up -d` to start Fluence node
|
||||||
3. Go back to `../example`
|
3. Go back to `../example`
|
||||||
4. Run `npm i`
|
4. Run `npm i`
|
||||||
5. Run `npm run start`
|
5. Run `npm run start`
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
1. Add the following to your dependencies
|
||||||
|
- `@fluencelabs/trust-graph`
|
||||||
|
- `@fluencelabs/aqua`
|
||||||
|
- `@fluencelabs/aqua-lib`
|
||||||
|
- `@fluencelabs/fluence`
|
||||||
|
- `@fluencelabs/fluence-network-environment`
|
||||||
|
|
||||||
|
2. Import dependencies
|
||||||
|
```typescript
|
||||||
|
import * as tg from "./generated/export";
|
||||||
|
import { Fluence, KeyPair } from "@fluencelabs/fluence";
|
||||||
|
import { krasnodar, Node } from "@fluencelabs/fluence-network-environment";
|
||||||
|
```
|
||||||
|
3. Add root and issue self-signed root trust.
|
||||||
|
4. For now, you can sign trusts/revocations only on js side with KeyPair.
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
|
|
||||||
import "@fluencelabs/trust-graph/trust-graph-api.aqua"
|
|
||||||
import "@fluencelabs/trust-graph/trust-graph.aqua"
|
|
||||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
|
||||||
|
|
||||||
export trusted_computation
|
|
||||||
|
|
||||||
service CertOp("op"):
|
|
||||||
array_length(a: []Certificate) -> u32
|
|
||||||
|
|
||||||
service TrustedComputation("op"):
|
|
||||||
identity(s: u64) -> u64
|
|
||||||
|
|
||||||
func trusted_computation(node: string) -> ?u64:
|
|
||||||
result: ?u64
|
|
||||||
-- on our trusted relay
|
|
||||||
on HOST_PEER_ID:
|
|
||||||
-- get all certificates issued for given node by our client's peer id
|
|
||||||
certs_result <- get_all_certs_from(node, %init_peer_id%)
|
|
||||||
if certs_result.success:
|
|
||||||
len <- CertOp.array_length(certs_result.certificates)
|
|
||||||
-- if there is any certificate node is trusted and computation is possible
|
|
||||||
if len != 0:
|
|
||||||
on node:
|
|
||||||
result <- TrustedComputation.identity(5)
|
|
||||||
|
|
||||||
<- result
|
|
@ -1,13 +1,10 @@
|
|||||||
import add_root_trust, add_trust, revoke from "@fluencelabs/trust-graph/trust-graph-api.aqua"
|
import get_trust_bytes, issue_trust, verify_trust, add_trust, add_root, get_weight, get_all_certs, insert_cert, get_revoke_bytes, issue_revocation, revoke, isFluencePeer from "../../aqua/trust-graph-api.aqua"
|
||||||
export add_root_trust, add_trust, revoke
|
|
||||||
import Peer from "@fluencelabs/aqua-lib/builtin.aqua"
|
|
||||||
|
|
||||||
alias PeerId: string
|
export get_trust_bytes, issue_trust, verify_trust, add_trust, add_root, get_weight, get_all_certs, insert_cert, get_revoke_bytes, issue_revocation, revoke, isFluencePeer
|
||||||
|
|
||||||
func timestamp_sec() -> u64:
|
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||||
on HOST_PEER_ID:
|
|
||||||
|
func timestamp_sec(node: string) -> u64:
|
||||||
|
on node:
|
||||||
result <- Peer.timestamp_sec()
|
result <- Peer.timestamp_sec()
|
||||||
<- result
|
<- result
|
||||||
|
|
||||||
service Sig:
|
|
||||||
sign(msg: []u8) -> []u8
|
|
||||||
|
143
example/index.ts
143
example/index.ts
@ -14,12 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {trusted_computation} from "./generated/computation";
|
|
||||||
import * as tg from "./generated/export";
|
import * as tg from "./generated/export";
|
||||||
import {Fluence, FluencePeer, KeyPair} from "@fluencelabs/fluence";
|
import { Fluence, KeyPair } from "@fluencelabs/fluence";
|
||||||
import {krasnodar, Node, testNet, stage} from "@fluencelabs/fluence-network-environment";
|
import { krasnodar, Node } from "@fluencelabs/fluence-network-environment";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import {add_root_trust, registerSig} from "./generated/export";
|
|
||||||
const bs58 = require('bs58');
|
const bs58 = require('bs58');
|
||||||
|
|
||||||
let local: Node[] = [
|
let local: Node[] = [
|
||||||
@ -33,106 +31,105 @@ let local: Node[] = [
|
|||||||
multiaddr:
|
multiaddr:
|
||||||
"/ip4/127.0.0.1/tcp/9991/ws/p2p/12D3KooWRABanQHUn28dxavN9ZS1zZghqoZVAYtFpoN7FdtoGTFv",
|
"/ip4/127.0.0.1/tcp/9991/ws/p2p/12D3KooWRABanQHUn28dxavN9ZS1zZghqoZVAYtFpoN7FdtoGTFv",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
peerId: "12D3KooWFpQ7LHxcC9FEBUh3k4nSCC12jBhijJv3gJbi7wsNYzJ5",
|
|
||||||
multiaddr:
|
|
||||||
"/ip4/127.0.0.1/tcp/9992/ws/p2p/12D3KooWFpQ7LHxcC9FEBUh3k4nSCC12jBhijJv3gJbi7wsNYzJ5",
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
async function revoke_all(relay: string, revoked_by: string) {
|
async function is_fluence_peer(relay: string) {
|
||||||
for (var node of local) {
|
let result = await tg.isFluencePeer(relay);
|
||||||
let error = await tg.revoke(relay, revoked_by, node.peerId);
|
|
||||||
console.log(error)
|
|
||||||
assert(error == null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async function add_root(relay: string, peer_id: string) {
|
|
||||||
let current_time = await tg.timestamp_sec();
|
|
||||||
let far_future = current_time + 9999999;
|
|
||||||
let error = await tg.add_root_trust(relay, peer_id, 2, far_future);
|
|
||||||
assert(error == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function add_new_trust_checked(relay: string, issuer: string, issued_for_peer_id: string, expires_at_sec: number) {
|
if (result) {
|
||||||
let error = await tg.add_trust(relay, issuer, issued_for_peer_id, expires_at_sec);
|
console.log("Current relay %s identified as Fluence Labs' peer", relay)
|
||||||
if (error !== null) {
|
|
||||||
console.error("%s", error);
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Trust issued for %s successfully added", issued_for_peer_id)
|
console.log("Current relay %s is not Fluence Labs' peer", relay)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function revoke_checked(relay: string, revoked_by: string, revoked_peer_id: string) {
|
async function add_trust_helper(relay: string, issuer_kp: KeyPair, issuer_peer_id: string, issued_for_peer_id: string, expires_at_sec: number, issued_at_sec: number) {
|
||||||
let error = await tg.revoke(relay, revoked_by, revoked_peer_id);
|
let trust_metadata = await tg.get_trust_bytes(relay, issued_for_peer_id, expires_at_sec, issued_at_sec);
|
||||||
if (error !== null) {
|
const signed_metadata = await issuer_kp.Libp2pPeerId.privKey.sign(Uint8Array.from(trust_metadata.result));
|
||||||
console.log("%s", error);
|
|
||||||
} else {
|
let trust = await tg.issue_trust(relay, issued_for_peer_id, expires_at_sec, issued_at_sec, Array.from(signed_metadata));
|
||||||
console.log("Trust issued for %s revoked", revoked_peer_id)
|
assert(trust.success)
|
||||||
}
|
|
||||||
|
let result = await tg.verify_trust(relay, trust.trust, issuer_peer_id);
|
||||||
|
assert(result.success)
|
||||||
|
|
||||||
|
let result_add = await tg.add_trust(relay, trust.trust, issuer_peer_id);
|
||||||
|
assert(result_add.success)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function exec_trusted_computation(node: string) {
|
async function revoke_helper(node: string, issuer_kp: KeyPair, revoked_by_peer_id: string, revoked_peer_id: string, revoked_at_sec: number) {
|
||||||
let result = await trusted_computation(node)
|
let trust_metadata = await tg.get_revoke_bytes(node, revoked_peer_id, revoked_at_sec);
|
||||||
|
const signed_metadata = await issuer_kp.Libp2pPeerId.privKey.sign(Uint8Array.from(trust_metadata.result));
|
||||||
|
|
||||||
if (result !== null) {
|
let revocation = await tg.issue_revocation(node, revoked_peer_id, revoked_by_peer_id, revoked_at_sec, Array.from(signed_metadata));
|
||||||
console.log("📗 Trusted computation on node %s successful, result is %s", node, result)
|
assert(revocation.success)
|
||||||
} else {
|
|
||||||
console.log("📕 Trusted computation on node %s failed", node)
|
let result_add = await tg.revoke(node, revocation.revocation);
|
||||||
}
|
assert(result_add.success)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log("In this example we try to execute some trusted computations based on trusts");
|
|
||||||
console.log("📘 Will connect to local nodes");
|
console.log("📘 Will connect to local nodes");
|
||||||
// key from local-network/builtins_secret_key.ed25519 to connect as builtins owner
|
// key from local-network/builtins_secret_key.ed25519 to connect as builtins owner
|
||||||
let sk = bs58.decode("5FwE32bDcphFzuMca7Y2qW1gdR64fTBYoRNvD4MLE1hecDGhCMQGKn8aseMr5wRo4Xo2CRFdrEAawUNLYkgQD78K").slice(0, 32); // first 32 bytes - secret key, second - public key
|
let sk = bs58.decode("5FwE32bDcphFzuMca7Y2qW1gdR64fTBYoRNvD4MLE1hecDGhCMQGKn8aseMr5wRo4Xo2CRFdrEAawUNLYkgQD78K").slice(0, 32); // first 32 bytes - secret key, second - public key
|
||||||
let builtins_keypair = await KeyPair.fromEd25519SK(sk);
|
let builtins_keypair = await KeyPair.fromEd25519SK(sk);
|
||||||
|
|
||||||
let relay = local[0];
|
await Fluence.start({ connectTo: local[0], KeyPair: builtins_keypair});
|
||||||
await Fluence.start({ connectTo: relay, KeyPair: builtins_keypair});
|
|
||||||
console.log(
|
console.log(
|
||||||
"📗 created a fluence peer %s with relay %s",
|
"📗 created a fluence peer %s with relay %s",
|
||||||
Fluence.getStatus().peerId,
|
Fluence.getStatus().peerId,
|
||||||
Fluence.getStatus().relayPeerId
|
Fluence.getStatus().relayPeerId
|
||||||
);
|
);
|
||||||
let local_peer_id = Fluence.getStatus().peerId;
|
let relay = local[0].peerId
|
||||||
assert(local_peer_id !== null);
|
|
||||||
|
|
||||||
let current_time = await tg.timestamp_sec();
|
|
||||||
let far_future = current_time + 9999999;
|
|
||||||
|
|
||||||
// clear all trusts from our peer id on relay
|
|
||||||
await revoke_all(relay.peerId, local_peer_id);
|
|
||||||
// wait to be sure that last revocation will be older than future trusts at least on 1 second (because timestamp in secs)
|
|
||||||
await new Promise(f => setTimeout(f, 1000));
|
|
||||||
|
|
||||||
// set our peer id as root to our relay
|
|
||||||
await add_root(relay.peerId, local_peer_id);
|
|
||||||
|
|
||||||
let nodeA = local[0].peerId
|
let nodeA = local[0].peerId
|
||||||
let nodeB = local[1].peerId
|
let nodeB = local[1].peerId
|
||||||
let nodeC = local[2].peerId
|
|
||||||
|
|
||||||
// try to exec computation on every node, will fail
|
// keypair if nodeA specified in local-network/docker-compose.yml
|
||||||
await exec_trusted_computation(nodeA); // fail
|
const issuer_kp = await KeyPair.fromEd25519SK(bs58.decode("29Apzfedhw2Jxh94Jj4rNSmavQ1TkNe8ALYRA7bMegobwp423aLrURxLk32WtXgXHDqoSz7GAT9fQfoMhVd1e5Ww"));
|
||||||
await exec_trusted_computation(nodeB); // fail
|
|
||||||
await exec_trusted_computation(nodeC); // fail
|
|
||||||
|
|
||||||
console.log("🌀 Issue trust to nodeB: %s", nodeB);
|
// set nodeA as a root
|
||||||
await add_new_trust_checked(relay.peerId, local_peer_id, nodeB, far_future);
|
let add_root_result = await tg.add_root(relay, nodeA, 2);
|
||||||
|
assert(add_root_result.success)
|
||||||
|
|
||||||
await exec_trusted_computation(nodeA); // fail
|
// add self-signed root trust
|
||||||
await exec_trusted_computation(nodeB); // success
|
const issued_timestamp_sec = await tg.timestamp_sec(relay);
|
||||||
await exec_trusted_computation(nodeC); // fail
|
const expires_at_sec = issued_timestamp_sec + 999999999;
|
||||||
|
await add_trust_helper(relay, issuer_kp, nodeA, nodeB, expires_at_sec, issued_timestamp_sec);
|
||||||
|
|
||||||
|
let root_weight_result = await tg.get_weight(relay, nodeA);
|
||||||
|
assert(root_weight_result.success)
|
||||||
|
console.log("Root weight (nodeA) is: %s", root_weight_result.weight);
|
||||||
|
|
||||||
|
// issue trust by nodeA to nodeB and add to tg
|
||||||
|
await add_trust_helper(relay, issuer_kp, nodeA, nodeB, expires_at_sec, issued_timestamp_sec);
|
||||||
|
let weight_result = await tg.get_weight(relay, nodeB);
|
||||||
|
console.log("Weight of nodeB: is %s", weight_result.weight);
|
||||||
|
|
||||||
|
assert(root_weight_result.weight / 2 === weight_result.weight);
|
||||||
|
|
||||||
|
let certs = await tg.get_all_certs(relay, nodeB);
|
||||||
|
assert(certs.certificates.length === 1);
|
||||||
|
console.log("There is one cert for nodeB with chain len %s", certs.certificates[0].chain.length);
|
||||||
|
console.log("It contains self-signed nodeA root trust and nodeA->nodeB trust");
|
||||||
|
|
||||||
|
// wait to create revoke after trust (because timestamp in secs)
|
||||||
await new Promise(f => setTimeout(f, 1000));
|
await new Promise(f => setTimeout(f, 1000));
|
||||||
console.log("🚫 Revoke trust to nodeB");
|
|
||||||
await revoke_checked(relay.peerId, local_peer_id, nodeB);
|
|
||||||
|
|
||||||
await exec_trusted_computation(nodeA); // fail
|
console.log("Now we will revoke trust for nodeB")
|
||||||
await exec_trusted_computation(nodeB); // fail
|
// revoke nodeB by nodeA
|
||||||
await exec_trusted_computation(nodeC); // fail
|
await revoke_helper(relay, issuer_kp, nodeA, nodeB, await tg.timestamp_sec(relay));
|
||||||
|
|
||||||
|
let empty_certs = await tg.get_all_certs(relay, nodeB);
|
||||||
|
assert(empty_certs.certificates.length === 0);
|
||||||
|
console.log("Now there is no certs for nodeB");
|
||||||
|
|
||||||
|
console.log("Let's check if our node is Fluence Labs peer");
|
||||||
|
await is_fluence_peer(relay);
|
||||||
|
|
||||||
|
console.log("Now let's check some krasnodar's node");
|
||||||
|
await is_fluence_peer(krasnodar[0].peerId);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5271
example/package-lock.json
generated
5271
example/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,9 +13,9 @@
|
|||||||
"author": "Fluence Labs",
|
"author": "Fluence Labs",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluencelabs/aqua": "^0.5.2-257",
|
"@fluencelabs/aqua": "0.5.0-247",
|
||||||
"@fluencelabs/aqua-lib": "^0.3.2",
|
"@fluencelabs/aqua-lib": "0.2.1",
|
||||||
"@fluencelabs/fluence": "^0.18.0",
|
"@fluencelabs/fluence": "0.15.1",
|
||||||
"@fluencelabs/fluence-network-environment": "^1.0.10",
|
"@fluencelabs/fluence-network-environment": "^1.0.10",
|
||||||
"@fluencelabs/trust-graph": "file:../aqua",
|
"@fluencelabs/trust-graph": "file:../aqua",
|
||||||
"bs58": "^4.0.1"
|
"bs58": "^4.0.1"
|
||||||
|
@ -1 +0,0 @@
|
|||||||
E5ay3731i4HN8XjJozouV92RDMGAn3qSnb9dKSnujiWv
|
|
@ -8,7 +8,7 @@ license = "Apache-2.0"
|
|||||||
repository = "https://github.com/fluencelabs/trust-graph"
|
repository = "https://github.com/fluencelabs/trust-graph"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "=1.0.118", features = ["derive"] }
|
serde = { version = "1.0.118", features = ["derive"] }
|
||||||
serde_json = "1.0.58"
|
serde_json = "1.0.58"
|
||||||
bs58 = "0.3.1"
|
bs58 = "0.3.1"
|
||||||
ed25519-dalek = { version = "1.0.1", features = ["serde", "std"] }
|
ed25519-dalek = { version = "1.0.1", features = ["serde", "std"] }
|
||||||
@ -23,7 +23,7 @@ asn1_der = "0.6.1"
|
|||||||
sha2 = "0.9.1"
|
sha2 = "0.9.1"
|
||||||
zeroize = "1"
|
zeroize = "1"
|
||||||
serde_bytes = "0.11"
|
serde_bytes = "0.11"
|
||||||
libp2p-core = { package = "fluence-fork-libp2p-core", version = "0.27.2", features = ["secp256k1"]}
|
libp2p-core = { version = "0.31", default-features = false, features = [ "secp256k1" ] }
|
||||||
eyre = "0.6.5"
|
eyre = "0.6.5"
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
|
3
keypair/rust-toolchain.toml
Normal file
3
keypair/rust-toolchain.toml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "nightly-2022-01-16"
|
||||||
|
targets = [ "x86_64-apple-darwin", "x86_64-unknown-linux-gnu" ]
|
@ -109,7 +109,7 @@ impl PublicKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_peer_id(&self) -> PeerId {
|
pub fn to_peer_id(&self) -> PeerId {
|
||||||
PeerId::from_public_key(self.clone().into())
|
PeerId::from_public_key(&self.clone().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_key_format(&self) -> KeyFormat {
|
pub fn get_key_format(&self) -> KeyFormat {
|
||||||
@ -164,13 +164,24 @@ impl TryFrom<libp2p_core::PeerId> for PublicKey {
|
|||||||
type Error = DecodingError;
|
type Error = DecodingError;
|
||||||
|
|
||||||
fn try_from(peer_id: libp2p_core::PeerId) -> Result<Self, Self::Error> {
|
fn try_from(peer_id: libp2p_core::PeerId) -> Result<Self, Self::Error> {
|
||||||
Ok(peer_id
|
Ok(as_public_key(&peer_id)
|
||||||
.as_public_key()
|
|
||||||
.ok_or(DecodingError::PublicKeyNotInlined(peer_id.to_base58()))?
|
.ok_or(DecodingError::PublicKeyNotInlined(peer_id.to_base58()))?
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert PeerId to libp2p's PublicKey
|
||||||
|
fn as_public_key(peer_id: &PeerId) -> Option<libp2p_core::PublicKey> {
|
||||||
|
use libp2p_core::multihash;
|
||||||
|
|
||||||
|
let mhash = peer_id.as_ref();
|
||||||
|
|
||||||
|
match multihash::Code::try_from(mhash.code()) {
|
||||||
|
Ok(multihash::Code::Identity) => libp2p_core::PublicKey::from_protobuf_encoding(mhash.digest()).ok(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
# management secret key is NAB5rGwT4qOEB+6nLQawkTfCOV2eiFSjgQK8bfEdZXY=
|
# management secret key is NAB5rGwT4qOEB+6nLQawkTfCOV2eiFSjgQK8bfEdZXY=
|
||||||
services:
|
services:
|
||||||
fluence-0: # /ip4/127.0.0.1/tcp/9990/ws/p2p/12D3KooWHBG9oaVx4i3vi6c1rSBUm7MLBmyGmmbHoZ23pmjDCnvK
|
fluence-0: # /ip4/127.0.0.1/tcp/9990/ws/p2p/12D3KooWHBG9oaVx4i3vi6c1rSBUm7MLBmyGmmbHoZ23pmjDCnvK
|
||||||
command: -f ed25519 -k 29Apzfedhw2Jxh94Jj4rNSmavQ1TkNe8ALYRA7bMegobwp423aLrURxLk32WtXgXHDqoSz7GAT9fQfoMhVd1e5Ww -m 12D3KooWFRgVmb1uWcmCbmJqLr8tBQghL6ysSpK2VyE2VZbaQ6wy -t 7770 -w 9990 --bootstraps /dns4/fluence-1/tcp/7771 /dns4/fluence-2/tcp/7772
|
command: -f ed25519 -k 29Apzfedhw2Jxh94Jj4rNSmavQ1TkNe8ALYRA7bMegobwp423aLrURxLk32WtXgXHDqoSz7GAT9fQfoMhVd1e5Ww -m 12D3KooWFRgVmb1uWcmCbmJqLr8tBQghL6ysSpK2VyE2VZbaQ6wy -t 7770 -w 9990 # --bootstraps /dns4/fluence-1/tcp/7771 /dns4/fluence-2/tcp/7772
|
||||||
container_name: fluence-0
|
container_name: fluence-0
|
||||||
environment:
|
environment:
|
||||||
RUST_BACKTRACE: full
|
RUST_BACKTRACE: full
|
||||||
RUST_LOG: info,network=trace,aquamarine=info,aquamarine::actor=info,tokio_threadpool=info,tokio_reactor=info,mio=info,tokio_io=info,soketto=info,yamux=info,multistream_select=info,libp2p_secio=info,libp2p_websocket::framed=info,libp2p_ping=info,libp2p_core::upgrade::apply=info,libp2p_kad::kbucket=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,particle_server::behaviour::identify=info,libp2p_mplex=info,libp2p_identify=info,walrus=info,particle_protocol::libp2p_protocol::upgrade=info,kademlia::behaviour=info
|
RUST_LOG: info,network=trace,aquamarine=info,aquamarine::actor=info,tokio_threadpool=info,tokio_reactor=info,mio=info,tokio_io=info,soketto=info,yamux=info,multistream_select=info,libp2p_secio=info,libp2p_websocket::framed=info,libp2p_ping=info,libp2p_core::upgrade::apply=info,libp2p_kad::kbucket=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,particle_server::behaviour::identify=info,libp2p_mplex=info,libp2p_identify=info,walrus=info,particle_protocol::libp2p_protocol::upgrade=info,kademlia::behaviour=info
|
||||||
WASM_LOG: info
|
WASM_LOG: info
|
||||||
image: fluencelabs/node:tg-hl-api_v345
|
image: fluencelabs/node:latest
|
||||||
ports:
|
ports:
|
||||||
- 7770:7770 # tcp
|
- 7770:7770 # tcp
|
||||||
- 9990:9990 # ws
|
- 9990:9990 # ws
|
||||||
- 5003:5001 # ipfs rpc
|
- 5002:5001 # ipfs rpc
|
||||||
- 4000:4001 # ipfs swarm
|
- 4000:4001 # ipfs swarm
|
||||||
- 18080:18080 # /metrics
|
- 18080:18080 # /metrics
|
||||||
restart: always
|
restart: always
|
||||||
@ -22,58 +22,56 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- fluence
|
- fluence
|
||||||
|
|
||||||
fluence-1: # /ip4/127.0.0.1/tcp/9991/ws/p2p/12D3KooWRABanQHUn28dxavN9ZS1zZghqoZVAYtFpoN7FdtoGTFv
|
# fluence-1: # /ip4/127.0.0.1/tcp/9991/ws/p2p/12D3KooWRABanQHUn28dxavN9ZS1zZghqoZVAYtFpoN7FdtoGTFv
|
||||||
command: -f ed25519 -k 5fNENMwkUT4dW3hPs9ZwqV4qA5pdTtUChTazAx9Awe2Vpz1yaJu3VCmcEZow6YgdFBGoZoFAZUZBbF3c2Ebd2iL -m 12D3KooWFRgVmb1uWcmCbmJqLr8tBQghL6ysSpK2VyE2VZbaQ6wy -t 7771 -w 9991 --bootstraps /dns4/fluence-0/tcp/7770 /dns4/fluence-2/tcp/7772 #/dns4/kras-00.fluence.dev/tcp/7770
|
# command: -f ed25519 -k 5fNENMwkUT4dW3hPs9ZwqV4qA5pdTtUChTazAx9Awe2Vpz1yaJu3VCmcEZow6YgdFBGoZoFAZUZBbF3c2Ebd2iL -m 12D3KooWFRgVmb1uWcmCbmJqLr8tBQghL6ysSpK2VyE2VZbaQ6wy -t 7771 -w 9991 --bootstraps /dns4/fluence-0/tcp/7770 /dns4/fluence-2/tcp/7772 #/dns4/kras-00.fluence.dev/tcp/7770
|
||||||
container_name: fluence-1
|
# container_name: fluence-1
|
||||||
environment:
|
# environment:
|
||||||
RUST_BACKTRACE: full
|
# RUST_BACKTRACE: full
|
||||||
RUST_LOG: info,network=trace,aquamarine=info,aquamarine::actor=info,tokio_threadpool=info,tokio_reactor=info,mio=info,tokio_io=info,soketto=info,yamux=info,multistream_select=info,libp2p_secio=info,libp2p_websocket::framed=info,libp2p_ping=info,libp2p_core::upgrade::apply=info,libp2p_kad::kbucket=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,particle_server::behaviour::identify=info,libp2p_mplex=info,libp2p_identify=info,walrus=info,particle_protocol::libp2p_protocol::upgrade=info,kademlia::behaviour=info
|
# RUST_LOG: info,network=trace,aquamarine=info,aquamarine::actor=info,tokio_threadpool=info,tokio_reactor=info,mio=info,tokio_io=info,soketto=info,yamux=info,multistream_select=info,libp2p_secio=info,libp2p_websocket::framed=info,libp2p_ping=info,libp2p_core::upgrade::apply=info,libp2p_kad::kbucket=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,particle_server::behaviour::identify=info,libp2p_mplex=info,libp2p_identify=info,walrus=info,particle_protocol::libp2p_protocol::upgrade=info,kademlia::behaviour=info
|
||||||
WASM_LOG: info
|
# WASM_LOG: info
|
||||||
image: fluencelabs/node:tg-hl-api_v345
|
# image: fluencelabs/node:latest
|
||||||
ports:
|
# ports:
|
||||||
- 7771:7771 # tcp
|
# - 7771:7771 # tcp
|
||||||
- 9991:9991 # ws
|
# - 9991:9991 # ws
|
||||||
- 5001:5001 # ipfs rpc
|
# - 5001:5001 # ipfs rpc
|
||||||
- 4001:4001 # ipfs swarm
|
# - 4001:4001 # ipfs swarm
|
||||||
- 18081:18080 # /metrics
|
# - 18081:18080 # /metrics
|
||||||
restart: always
|
# restart: always
|
||||||
volumes:
|
# volumes:
|
||||||
- fluence-1:/.fluence
|
# - fluence-1:/.fluence
|
||||||
- data-1:/config
|
# - data-1:/config
|
||||||
- ./builtins_secret_key.ed25519:/.fluence/v1/builtins_secret_key.ed25519
|
# networks:
|
||||||
networks:
|
# - fluence
|
||||||
- fluence
|
#
|
||||||
|
# fluence-2: # /ip4/127.0.0.1/tcp/9992/ws/p2p/12D3KooWFpQ7LHxcC9FEBUh3k4nSCC12jBhijJv3gJbi7wsNYzJ5
|
||||||
fluence-2: # /ip4/127.0.0.1/tcp/9992/ws/p2p/12D3KooWFpQ7LHxcC9FEBUh3k4nSCC12jBhijJv3gJbi7wsNYzJ5
|
# command: -f ed25519 -k 5DTs9LQS8Ay2dM8xBcikDRwYLMcanhsC6tynSSgpLyBZEv5Ey34LVw1fYcCuUj9A9EfvQJB2bsaGhSRoHQ7D6UE5 -m 12D3KooWFRgVmb1uWcmCbmJqLr8tBQghL6ysSpK2VyE2VZbaQ6wy -t 7772 -w 9992 --bootstraps /dns4/fluence-0/tcp/7770 /dns4/fluence-1/tcp/7771 #/dns4/kras-00.fluence.dev/tcp/7770
|
||||||
command: -f ed25519 -k 5DTs9LQS8Ay2dM8xBcikDRwYLMcanhsC6tynSSgpLyBZEv5Ey34LVw1fYcCuUj9A9EfvQJB2bsaGhSRoHQ7D6UE5 -m 12D3KooWFRgVmb1uWcmCbmJqLr8tBQghL6ysSpK2VyE2VZbaQ6wy -t 7772 -w 9992 --bootstraps /dns4/fluence-0/tcp/7770 /dns4/fluence-1/tcp/7771 #/dns4/kras-00.fluence.dev/tcp/7770
|
# container_name: fluence-2
|
||||||
container_name: fluence-2
|
# environment:
|
||||||
environment:
|
# RUST_BACKTRACE: full
|
||||||
RUST_BACKTRACE: full
|
# RUST_LOG: info,network=trace,aquamarine=info,aquamarine::actor=info,tokio_threadpool=info,tokio_reactor=info,mio=info,tokio_io=info,soketto=info,yamux=info,multistream_select=info,libp2p_secio=info,libp2p_websocket::framed=info,libp2p_ping=info,libp2p_core::upgrade::apply=info,libp2p_kad::kbucket=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,particle_server::behaviour::identify=info,libp2p_mplex=info,libp2p_identify=info,walrus=info,particle_protocol::libp2p_protocol::upgrade=info,kademlia::behaviour=info
|
||||||
RUST_LOG: info,network=trace,aquamarine=info,aquamarine::actor=info,tokio_threadpool=info,tokio_reactor=info,mio=info,tokio_io=info,soketto=info,yamux=info,multistream_select=info,libp2p_secio=info,libp2p_websocket::framed=info,libp2p_ping=info,libp2p_core::upgrade::apply=info,libp2p_kad::kbucket=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,cranelift_codegen=info,wasmer_wasi=info,async_io=info,polling=info,wasmer_interface_types_fl=info,particle_server::behaviour::identify=info,libp2p_mplex=info,libp2p_identify=info,walrus=info,particle_protocol::libp2p_protocol::upgrade=info,kademlia::behaviour=info
|
# WASM_LOG: info
|
||||||
WASM_LOG: info
|
# image: fluencelabs/node:latest
|
||||||
image: fluencelabs/node:tg-hl-api_v345
|
# ports:
|
||||||
ports:
|
# - 7772:7772 # tcp
|
||||||
- 7772:7772 # tcp
|
# - 9992:9992 # ws
|
||||||
- 9992:9992 # ws
|
# - 5002:5001 # ipfs rpc
|
||||||
- 5002:5001 # ipfs rpc
|
# - 4002:4001 # ipfs swarm
|
||||||
- 4002:4001 # ipfs swarm
|
# - 18082:18080 # /metrics
|
||||||
- 18082:18080 # /metrics
|
# restart: always
|
||||||
restart: always
|
# volumes:
|
||||||
volumes:
|
# - fluence-2:/.fluence
|
||||||
- fluence-2:/.fluence
|
# - data-2:/config
|
||||||
- data-2:/config
|
# networks:
|
||||||
- ./builtins_secret_key.ed25519:/.fluence/v1/builtins_secret_key.ed25519
|
# - fluence
|
||||||
networks:
|
|
||||||
- fluence
|
|
||||||
|
|
||||||
version: "3.5"
|
version: "3.5"
|
||||||
volumes:
|
volumes:
|
||||||
fluence-0:
|
fluence-0:
|
||||||
fluence-1:
|
# fluence-1:
|
||||||
fluence-2:
|
# fluence-2:
|
||||||
data-0:
|
data-0:
|
||||||
data-1:
|
# data-1:
|
||||||
data-2:
|
# data-2:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
fluence:
|
fluence:
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2021-09-01"
|
channel = "nightly-2022-01-16"
|
||||||
targets = [ "x86_64-apple-darwin", "x86_64-unknown-linux-gnu" ]
|
targets = [ "x86_64-apple-darwin", "x86_64-unknown-linux-gnu" ]
|
@ -16,7 +16,7 @@ fluence-keypair = { version = "0.5.0", path = "../keypair" }
|
|||||||
marine-rs-sdk = { version = "0.6.14", features = ["logger"] }
|
marine-rs-sdk = { version = "0.6.14", features = ["logger"] }
|
||||||
marine-sqlite-connector = "0.5.2"
|
marine-sqlite-connector = "0.5.2"
|
||||||
|
|
||||||
libp2p-core = { package = "fluence-fork-libp2p-core", version = "0.27.2", features = ["secp256k1"]}
|
libp2p-core = { version = "0.31", default-features = false, features = [ "secp256k1" ] }
|
||||||
|
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
anyhow = "1.0.31"
|
anyhow = "1.0.31"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2021-09-01"
|
channel = "nightly-2022-01-16"
|
||||||
targets = [ "x86_64-apple-darwin", "x86_64-unknown-linux-gnu" ]
|
targets = [ "x86_64-apple-darwin", "x86_64-unknown-linux-gnu" ]
|
@ -60,9 +60,9 @@ pub struct AllCertsResult {
|
|||||||
impl From<Result<Vec<Certificate>, ServiceError>> for AllCertsResult {
|
impl From<Result<Vec<Certificate>, ServiceError>> for AllCertsResult {
|
||||||
fn from(result: Result<Vec<Certificate>, ServiceError>) -> Self {
|
fn from(result: Result<Vec<Certificate>, ServiceError>) -> Self {
|
||||||
match result {
|
match result {
|
||||||
Ok(certificates) => AllCertsResult {
|
Ok(certs) => AllCertsResult {
|
||||||
success: true,
|
success: true,
|
||||||
certificates,
|
certificates: certs,
|
||||||
error: "".to_string(),
|
error: "".to_string(),
|
||||||
},
|
},
|
||||||
Err(e) => AllCertsResult {
|
Err(e) => AllCertsResult {
|
||||||
@ -75,19 +75,19 @@ impl From<Result<Vec<Certificate>, ServiceError>> for AllCertsResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
pub struct SetRootResult {
|
pub struct AddRootResult {
|
||||||
pub success: bool,
|
pub success: bool,
|
||||||
pub error: String,
|
pub error: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Result<(), ServiceError>> for SetRootResult {
|
impl From<Result<(), ServiceError>> for AddRootResult {
|
||||||
fn from(result: Result<(), ServiceError>) -> Self {
|
fn from(result: Result<(), ServiceError>) -> Self {
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => SetRootResult {
|
Ok(()) => AddRootResult {
|
||||||
success: true,
|
success: true,
|
||||||
error: "".to_string(),
|
error: "".to_string(),
|
||||||
},
|
},
|
||||||
Err(e) => SetRootResult {
|
Err(e) => AddRootResult {
|
||||||
success: false,
|
success: false,
|
||||||
error: format!("{}", e),
|
error: format!("{}", e),
|
||||||
},
|
},
|
||||||
@ -256,27 +256,3 @@ impl From<Result<(), ServiceError>> for RevokeResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
|
||||||
pub struct ExportRevocationsResult {
|
|
||||||
pub success: bool,
|
|
||||||
pub revocations: Vec<Revocation>,
|
|
||||||
pub error: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Result<Vec<Revocation>, ServiceError>> for ExportRevocationsResult {
|
|
||||||
fn from(result: Result<Vec<Revocation>, ServiceError>) -> Self {
|
|
||||||
match result {
|
|
||||||
Ok(revocations) => ExportRevocationsResult {
|
|
||||||
success: true,
|
|
||||||
revocations,
|
|
||||||
error: "".to_string(),
|
|
||||||
},
|
|
||||||
Err(e) => ExportRevocationsResult {
|
|
||||||
success: false,
|
|
||||||
revocations: vec![],
|
|
||||||
error: format!("{}", e),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,9 +2,9 @@ use crate::dto::{Certificate, Revocation, Trust};
|
|||||||
use crate::error::ServiceError;
|
use crate::error::ServiceError;
|
||||||
use crate::misc::{check_timestamp_tetraplets, extract_public_key, with_tg, wrapped_try};
|
use crate::misc::{check_timestamp_tetraplets, extract_public_key, with_tg, wrapped_try};
|
||||||
use crate::results::{
|
use crate::results::{
|
||||||
AddTrustResult, AllCertsResult, ExportRevocationsResult, GetRevokeBytesResult,
|
AddRootResult, AddTrustResult, AllCertsResult, GetRevokeBytesResult, GetTrustBytesResult,
|
||||||
GetTrustBytesResult, InsertResult, IssueRevocationResult, IssueTrustResult, RevokeResult,
|
InsertResult, IssueRevocationResult, IssueTrustResult, RevokeResult, VerifyTrustResult,
|
||||||
SetRootResult, VerifyTrustResult, WeightResult,
|
WeightResult,
|
||||||
};
|
};
|
||||||
use crate::storage_impl::SQLiteStorage;
|
use crate::storage_impl::SQLiteStorage;
|
||||||
use fluence_keypair::Signature;
|
use fluence_keypair::Signature;
|
||||||
@ -12,22 +12,27 @@ use marine_rs_sdk::{get_call_parameters, marine, CallParameters};
|
|||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use trust_graph::TrustGraph;
|
use trust_graph::{TrustGraph, MAX_WEIGHT_FACTOR};
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
/// could set only a owner of a trust graph service
|
fn get_weight_factor(max_chain_len: u32) -> u32 {
|
||||||
fn set_root(peer_id: String, max_chain_len: u32) -> SetRootResult {
|
MAX_WEIGHT_FACTOR.checked_sub(max_chain_len).unwrap_or(0u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
/// could add only a owner of a trust graph service
|
||||||
|
fn add_root(peer_id: String, weight_factor: u32) -> AddRootResult {
|
||||||
let call_parameters: CallParameters = marine_rs_sdk::get_call_parameters();
|
let call_parameters: CallParameters = marine_rs_sdk::get_call_parameters();
|
||||||
let init_peer_id = call_parameters.init_peer_id;
|
let init_peer_id = call_parameters.init_peer_id;
|
||||||
if call_parameters.service_creator_peer_id == init_peer_id {
|
if call_parameters.service_creator_peer_id == init_peer_id {
|
||||||
with_tg(|tg| {
|
with_tg(|tg| {
|
||||||
let public_key = extract_public_key(peer_id)?;
|
let public_key = extract_public_key(peer_id)?;
|
||||||
tg.set_root(public_key, max_chain_len)?;
|
tg.add_root_weight_factor(public_key, weight_factor)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
return SetRootResult {
|
return AddRootResult {
|
||||||
success: false,
|
success: false,
|
||||||
error: ServiceError::NotOwner.to_string(),
|
error: ServiceError::NotOwner.to_string(),
|
||||||
};
|
};
|
||||||
@ -66,40 +71,17 @@ fn get_certs(
|
|||||||
tg: &mut TrustGraph<SQLiteStorage>,
|
tg: &mut TrustGraph<SQLiteStorage>,
|
||||||
issued_for: String,
|
issued_for: String,
|
||||||
timestamp_sec: u64,
|
timestamp_sec: u64,
|
||||||
) -> Result<Vec<Certificate>, ServiceError> {
|
) -> Result<impl Iterator<Item = Certificate>, ServiceError> {
|
||||||
let public_key = extract_public_key(issued_for)?;
|
let public_key = extract_public_key(issued_for)?;
|
||||||
let certs = tg.get_all_certs(public_key, Duration::from_secs(timestamp_sec))?;
|
let certs = tg.get_all_certs(public_key, Duration::from_secs(timestamp_sec))?;
|
||||||
Ok(certs.into_iter().map(|c| c.into()).collect())
|
Ok(certs.into_iter().map(|c| c.into()))
|
||||||
}
|
|
||||||
|
|
||||||
fn get_certs_from(
|
|
||||||
tg: &mut TrustGraph<SQLiteStorage>,
|
|
||||||
issued_for: String,
|
|
||||||
issuer: String,
|
|
||||||
timestamp_sec: u64,
|
|
||||||
) -> Result<Vec<Certificate>, ServiceError> {
|
|
||||||
let issued_for_pk = extract_public_key(issued_for)?;
|
|
||||||
let issuer_pk = extract_public_key(issuer)?;
|
|
||||||
let certs =
|
|
||||||
tg.get_all_certs_from(issued_for_pk, issuer_pk, Duration::from_secs(timestamp_sec))?;
|
|
||||||
Ok(certs.into_iter().map(|c| c.into()).collect())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
fn get_all_certs(issued_for: String, timestamp_sec: u64) -> AllCertsResult {
|
fn get_all_certs(issued_for: String, timestamp_sec: u64) -> AllCertsResult {
|
||||||
with_tg(|tg| {
|
with_tg(|tg| {
|
||||||
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
|
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
|
||||||
get_certs(tg, issued_for, timestamp_sec)
|
get_certs(tg, issued_for, timestamp_sec).map(|iter| iter.collect())
|
||||||
})
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[marine]
|
|
||||||
fn get_all_certs_from(issued_for: String, issuer: String, timestamp_sec: u64) -> AllCertsResult {
|
|
||||||
with_tg(|tg| {
|
|
||||||
let cp = get_call_parameters();
|
|
||||||
check_timestamp_tetraplets(&cp, 1)?;
|
|
||||||
get_certs_from(tg, issued_for, issuer, timestamp_sec)
|
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
@ -109,7 +91,7 @@ fn get_host_certs(timestamp_sec: u64) -> AllCertsResult {
|
|||||||
with_tg(|tg| {
|
with_tg(|tg| {
|
||||||
let cp = marine_rs_sdk::get_call_parameters();
|
let cp = marine_rs_sdk::get_call_parameters();
|
||||||
check_timestamp_tetraplets(&cp, 0)?;
|
check_timestamp_tetraplets(&cp, 0)?;
|
||||||
get_certs(tg, cp.host_id, timestamp_sec)
|
get_certs(tg, cp.host_id, timestamp_sec).map(|iter| iter.collect())
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
@ -119,7 +101,10 @@ fn get_host_certs_from(issuer: String, timestamp_sec: u64) -> AllCertsResult {
|
|||||||
with_tg(|tg| {
|
with_tg(|tg| {
|
||||||
let cp = get_call_parameters();
|
let cp = get_call_parameters();
|
||||||
check_timestamp_tetraplets(&cp, 1)?;
|
check_timestamp_tetraplets(&cp, 1)?;
|
||||||
get_certs_from(tg, cp.host_id, issuer, timestamp_sec)
|
get_certs(tg, cp.host_id, timestamp_sec).map(|c| {
|
||||||
|
c.filter(|cert: &Certificate| cert.chain.iter().any(|t| t.issued_for == issuer))
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
@ -136,20 +121,6 @@ fn get_weight(peer_id: String, timestamp_sec: u64) -> WeightResult {
|
|||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
|
||||||
fn get_weight_from(peer_id: String, issuer: String, timestamp_sec: u64) -> WeightResult {
|
|
||||||
with_tg(|tg| {
|
|
||||||
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
|
|
||||||
let issued_for_pk = extract_public_key(peer_id.clone())?;
|
|
||||||
let issuer_pk = extract_public_key(issuer)?;
|
|
||||||
let weight =
|
|
||||||
tg.weight_from(issued_for_pk, issuer_pk, Duration::from_secs(timestamp_sec))?;
|
|
||||||
Ok(weight)
|
|
||||||
})
|
|
||||||
.map(|w| (w, peer_id))
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
fn get_trust_bytes(
|
fn get_trust_bytes(
|
||||||
issued_for_peer_id: String,
|
issued_for_peer_id: String,
|
||||||
@ -216,17 +187,18 @@ fn add_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> AddTru
|
|||||||
return Err(ServiceError::InvalidTimestamp("trust".to_string()));
|
return Err(ServiceError::InvalidTimestamp("trust".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tg.add_trust(
|
tg.add_trust(
|
||||||
&trust.try_into()?,
|
&trust.try_into()?,
|
||||||
public_key,
|
public_key,
|
||||||
Duration::from_secs(timestamp_sec),
|
Duration::from_secs(timestamp_sec),
|
||||||
)?)
|
)
|
||||||
|
.map_err(ServiceError::TGError)
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
fn get_revocation_bytes(revoked_peer_id: String, revoked_at: u64) -> GetRevokeBytesResult {
|
fn get_revoke_bytes(revoked_peer_id: String, revoked_at: u64) -> GetRevokeBytesResult {
|
||||||
wrapped_try(|| {
|
wrapped_try(|| {
|
||||||
let public_key = extract_public_key(revoked_peer_id)?;
|
let public_key = extract_public_key(revoked_peer_id)?;
|
||||||
Ok(trust_graph::Revocation::signature_bytes(
|
Ok(trust_graph::Revocation::signature_bytes(
|
||||||
@ -239,8 +211,8 @@ fn get_revocation_bytes(revoked_peer_id: String, revoked_at: u64) -> GetRevokeBy
|
|||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
fn issue_revocation(
|
fn issue_revocation(
|
||||||
revoked_by_peer_id: String,
|
|
||||||
revoked_peer_id: String,
|
revoked_peer_id: String,
|
||||||
|
revoked_by_peer_id: String,
|
||||||
revoked_at_sec: u64,
|
revoked_at_sec: u64,
|
||||||
signature_bytes: Vec<u8>,
|
signature_bytes: Vec<u8>,
|
||||||
) -> IssueRevocationResult {
|
) -> IssueRevocationResult {
|
||||||
@ -250,7 +222,7 @@ fn issue_revocation(
|
|||||||
|
|
||||||
let revoked_at = Duration::from_secs(revoked_at_sec);
|
let revoked_at = Duration::from_secs(revoked_at_sec);
|
||||||
let signature = Signature::from_bytes(revoked_by_pk.get_key_format(), signature_bytes);
|
let signature = Signature::from_bytes(revoked_by_pk.get_key_format(), signature_bytes);
|
||||||
Ok(trust_graph::Revocation::new(revoked_by_pk, revoked_pk, revoked_at, signature).into())
|
Ok(trust_graph::Revocation::new(revoked_pk, revoked_by_pk, revoked_at, signature).into())
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
@ -264,20 +236,7 @@ fn revoke(revoke: Revocation, timestamp_sec: u64) -> RevokeResult {
|
|||||||
return Err(ServiceError::InvalidTimestamp("revoke".to_string()));
|
return Err(ServiceError::InvalidTimestamp("revoke".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tg.revoke(revoke.try_into()?)?)
|
tg.revoke(revoke.try_into()?).map_err(ServiceError::TGError)
|
||||||
})
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[marine]
|
|
||||||
fn export_revocations(issued_for: String) -> ExportRevocationsResult {
|
|
||||||
with_tg(|tg| {
|
|
||||||
let issued_for_pk = extract_public_key(issued_for)?;
|
|
||||||
Ok(tg
|
|
||||||
.get_revocations(issued_for_pk)?
|
|
||||||
.into_iter()
|
|
||||||
.map(|r| r.into())
|
|
||||||
.collect())
|
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ impl Storage for SQLiteStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_root_weight_factor(
|
fn add_root_weight_factor(
|
||||||
&mut self,
|
&mut self,
|
||||||
pk: PK,
|
pk: PK,
|
||||||
weight_factor: WeightFactor,
|
weight_factor: WeightFactor,
|
||||||
@ -321,6 +321,7 @@ impl Storage for SQLiteStorage {
|
|||||||
let mut roots = vec![];
|
let mut roots = vec![];
|
||||||
|
|
||||||
while let Some(row) = cursor.next()? {
|
while let Some(row) = cursor.next()? {
|
||||||
|
log::info!("row: {:?}", row);
|
||||||
let pk = row[0].as_string().ok_or(PublicKeyConversion)?;
|
let pk = row[0].as_string().ok_or(PublicKeyConversion)?;
|
||||||
let pk: PK = PK::from_str(pk).map_err(|e| PublicKeyFromStr(e.to_string()))?;
|
let pk: PK = PK::from_str(pk).map_err(|e| PublicKeyFromStr(e.to_string()))?;
|
||||||
|
|
||||||
|
@ -87,8 +87,8 @@ mod service_tests {
|
|||||||
cp
|
cp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_root_peer_id(trust_graph: &mut ServiceInterface, peer_id: PeerId, max_chain_len: u32) {
|
fn add_root_peer_id(trust_graph: &mut ServiceInterface, peer_id: PeerId, weight_factor: u32) {
|
||||||
let result = trust_graph.set_root(peer_id.to_base58(), max_chain_len);
|
let result = trust_graph.add_root(peer_id.to_base58(), weight_factor);
|
||||||
assert!(result.success, "{}", result.error);
|
assert!(result.success, "{}", result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,9 +97,9 @@ mod service_tests {
|
|||||||
issuer_kp: &KeyPair,
|
issuer_kp: &KeyPair,
|
||||||
issued_at_sec: u64,
|
issued_at_sec: u64,
|
||||||
expires_at_sec: u64,
|
expires_at_sec: u64,
|
||||||
max_chain_len: u32,
|
weight_factor: u32,
|
||||||
) -> Trust {
|
) -> Trust {
|
||||||
let result = trust_graph.set_root(issuer_kp.get_peer_id().to_base58(), max_chain_len);
|
let result = trust_graph.add_root(issuer_kp.get_peer_id().to_base58(), weight_factor);
|
||||||
assert!(result.success, "{}", result.error);
|
assert!(result.success, "{}", result.error);
|
||||||
add_trust(
|
add_trust(
|
||||||
trust_graph,
|
trust_graph,
|
||||||
@ -201,13 +201,13 @@ mod service_tests {
|
|||||||
revoked_peer_id: &PeerId,
|
revoked_peer_id: &PeerId,
|
||||||
revoked_at_sec: u64,
|
revoked_at_sec: u64,
|
||||||
) -> Revocation {
|
) -> Revocation {
|
||||||
let result = trust_graph.get_revocation_bytes(revoked_peer_id.to_base58(), revoked_at_sec);
|
let result = trust_graph.get_revoke_bytes(revoked_peer_id.to_base58(), revoked_at_sec);
|
||||||
assert!(result.success, "{}", result.error);
|
assert!(result.success, "{}", result.error);
|
||||||
|
|
||||||
let revoke_bytes = issuer_kp.sign(&result.result).unwrap().to_vec().to_vec();
|
let revoke_bytes = issuer_kp.sign(&result.result).unwrap().to_vec().to_vec();
|
||||||
let issue_result = trust_graph.issue_revocation(
|
let issue_result = trust_graph.issue_revocation(
|
||||||
issuer_kp.get_peer_id().to_base58(),
|
|
||||||
revoked_peer_id.to_base58(),
|
revoked_peer_id.to_base58(),
|
||||||
|
issuer_kp.get_peer_id().to_base58(),
|
||||||
revoked_at_sec,
|
revoked_at_sec,
|
||||||
revoke_bytes,
|
revoke_bytes,
|
||||||
);
|
);
|
||||||
@ -325,7 +325,7 @@ mod service_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let some_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
let some_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
||||||
let result = trust_graph.set_root_cp(some_peer_id.to_base58(), 0, cp);
|
let result = trust_graph.add_root_cp(some_peer_id.to_base58(), 0, cp);
|
||||||
assert!(!result.success);
|
assert!(!result.success);
|
||||||
assert_eq!(result.error, ServiceError::NotOwner.to_string());
|
assert_eq!(result.error, ServiceError::NotOwner.to_string());
|
||||||
}
|
}
|
||||||
@ -343,7 +343,7 @@ mod service_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let some_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
let some_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
||||||
let result = trust_graph.set_root_cp(some_peer_id.to_base58(), 0, cp);
|
let result = trust_graph.add_root_cp(some_peer_id.to_base58(), 0, cp);
|
||||||
assert!(result.success, "{}", result.error);
|
assert!(result.success, "{}", result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ mod service_tests {
|
|||||||
let expires_at_sec = 9999u64;
|
let expires_at_sec = 9999u64;
|
||||||
let issued_at_sec = 0u64;
|
let issued_at_sec = 0u64;
|
||||||
|
|
||||||
set_root_peer_id(&mut trust_graph, root_kp.get_peer_id(), 4u32);
|
add_root_peer_id(&mut trust_graph, root_kp.get_peer_id(), 4u32);
|
||||||
|
|
||||||
let result =
|
let result =
|
||||||
trust_graph.get_trust_bytes(root_peer_id.to_base58(), expires_at_sec, issued_at_sec);
|
trust_graph.get_trust_bytes(root_peer_id.to_base58(), expires_at_sec, issued_at_sec);
|
||||||
@ -408,7 +408,7 @@ mod service_tests {
|
|||||||
&root_kp,
|
&root_kp,
|
||||||
cur_time,
|
cur_time,
|
||||||
root_expired_time - 1,
|
root_expired_time - 1,
|
||||||
10,
|
4,
|
||||||
);
|
);
|
||||||
|
|
||||||
let trust_kp = KeyPair::generate_ed25519();
|
let trust_kp = KeyPair::generate_ed25519();
|
||||||
@ -447,7 +447,7 @@ mod service_tests {
|
|||||||
|
|
||||||
let peerA_kp = KeyPair::generate_ed25519();
|
let peerA_kp = KeyPair::generate_ed25519();
|
||||||
let mut cur_time = 100u64;
|
let mut cur_time = 100u64;
|
||||||
add_root_with_trust(&mut trust_graph, &peerA_kp, cur_time, cur_time + 9999, 10);
|
add_root_with_trust(&mut trust_graph, &peerA_kp, cur_time, cur_time + 9999, 4u32);
|
||||||
|
|
||||||
let peerB_kp = KeyPair::generate_ed25519();
|
let peerB_kp = KeyPair::generate_ed25519();
|
||||||
add_trust(
|
add_trust(
|
||||||
@ -490,7 +490,7 @@ mod service_tests {
|
|||||||
let mut cur_time = current_time();
|
let mut cur_time = current_time();
|
||||||
|
|
||||||
let root_peer_id = key_pairs[0].get_peer_id();
|
let root_peer_id = key_pairs[0].get_peer_id();
|
||||||
set_root_peer_id(&mut trust_graph, root_peer_id, 10);
|
add_root_peer_id(&mut trust_graph, root_peer_id, 2);
|
||||||
add_trusts(&mut trust_graph, &trusts, cur_time);
|
add_trusts(&mut trust_graph, &trusts, cur_time);
|
||||||
|
|
||||||
let target_peer_id = key_pairs[4].get_peer_id();
|
let target_peer_id = key_pairs[4].get_peer_id();
|
||||||
@ -536,7 +536,7 @@ mod service_tests {
|
|||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
|
|
||||||
let root_peer_id = key_pairs[0].get_peer_id();
|
let root_peer_id = key_pairs[0].get_peer_id();
|
||||||
set_root_peer_id(&mut trust_graph, root_peer_id, 10);
|
add_root_peer_id(&mut trust_graph, root_peer_id, 2);
|
||||||
add_trusts(&mut trust_graph, &trusts, cur_time);
|
add_trusts(&mut trust_graph, &trusts, cur_time);
|
||||||
|
|
||||||
let issued_by = key_pairs.last().unwrap().get_peer_id();
|
let issued_by = key_pairs.last().unwrap().get_peer_id();
|
||||||
@ -577,7 +577,7 @@ mod service_tests {
|
|||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
|
|
||||||
let root1_peer_id = key_pairs[0].get_peer_id();
|
let root1_peer_id = key_pairs[0].get_peer_id();
|
||||||
set_root_peer_id(&mut trust_graph, root1_peer_id, 10);
|
add_root_peer_id(&mut trust_graph, root1_peer_id, 2);
|
||||||
add_trusts(&mut trust_graph, &trusts, cur_time);
|
add_trusts(&mut trust_graph, &trusts, cur_time);
|
||||||
|
|
||||||
let issued_by = key_pairs.last().unwrap().get_peer_id();
|
let issued_by = key_pairs.last().unwrap().get_peer_id();
|
||||||
@ -620,7 +620,7 @@ mod service_tests {
|
|||||||
|
|
||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
let root_peer_id = key_pairs[0].get_peer_id();
|
let root_peer_id = key_pairs[0].get_peer_id();
|
||||||
set_root_peer_id(&mut trust_graph, root_peer_id, 10);
|
add_root_peer_id(&mut trust_graph, root_peer_id, 1);
|
||||||
|
|
||||||
for auth in trusts.iter() {
|
for auth in trusts.iter() {
|
||||||
add_trust_checked(&mut trust_graph, auth.trust.clone(), auth.issuer, cur_time);
|
add_trust_checked(&mut trust_graph, auth.trust.clone(), auth.issuer, cur_time);
|
||||||
@ -649,9 +649,9 @@ mod service_tests {
|
|||||||
let far_future = cur_time + 9999;
|
let far_future = cur_time + 9999;
|
||||||
|
|
||||||
// add first and last trusts as roots
|
// add first and last trusts as roots
|
||||||
set_root_peer_id(&mut trust_graph, kps[0].get_peer_id(), 10);
|
add_root_peer_id(&mut trust_graph, kps[0].get_peer_id(), 0);
|
||||||
add_trusts(&mut trust_graph, &trusts, cur_time);
|
add_trusts(&mut trust_graph, &trusts, cur_time);
|
||||||
add_root_with_trust(&mut trust_graph, &kps[5], cur_time, far_future, 10);
|
add_root_with_trust(&mut trust_graph, &kps[5], cur_time, far_future, 0);
|
||||||
|
|
||||||
let certs = get_all_certs(&mut trust_graph, kps[5].get_peer_id(), cur_time);
|
let certs = get_all_certs(&mut trust_graph, kps[5].get_peer_id(), cur_time);
|
||||||
// first with self-signed last trust, second - without
|
// first with self-signed last trust, second - without
|
||||||
@ -667,7 +667,7 @@ mod service_tests {
|
|||||||
|
|
||||||
let root_kp = KeyPair::generate_ed25519();
|
let root_kp = KeyPair::generate_ed25519();
|
||||||
let cur_time = 100u64;
|
let cur_time = 100u64;
|
||||||
add_root_with_trust(&mut trust_graph, &root_kp, cur_time, cur_time + 999, 10);
|
add_root_with_trust(&mut trust_graph, &root_kp, cur_time, cur_time + 999, 4u32);
|
||||||
|
|
||||||
let trust_kp = KeyPair::generate_ed25519();
|
let trust_kp = KeyPair::generate_ed25519();
|
||||||
add_trust(
|
add_trust(
|
||||||
@ -712,7 +712,7 @@ mod service_tests {
|
|||||||
|
|
||||||
let root_kp = KeyPair::generate_ed25519();
|
let root_kp = KeyPair::generate_ed25519();
|
||||||
let mut cur_time = 100u64;
|
let mut cur_time = 100u64;
|
||||||
add_root_with_trust(&mut trust_graph, &root_kp, cur_time, cur_time + 999, 10);
|
add_root_with_trust(&mut trust_graph, &root_kp, cur_time, cur_time + 999, 4u32);
|
||||||
|
|
||||||
let trust_kp = KeyPair::generate_ed25519();
|
let trust_kp = KeyPair::generate_ed25519();
|
||||||
let expires_at_sec = cur_time + 10;
|
let expires_at_sec = cur_time + 10;
|
||||||
@ -752,10 +752,10 @@ mod service_tests {
|
|||||||
let root2_kp = KeyPair::generate_ed25519();
|
let root2_kp = KeyPair::generate_ed25519();
|
||||||
let cur_time = 100;
|
let cur_time = 100;
|
||||||
let far_future = cur_time + 99999;
|
let far_future = cur_time + 99999;
|
||||||
// root with bigger weight (bigger max_chain_len)
|
// root with bigger weight (smaller weight factor)
|
||||||
add_root_with_trust(&mut trust_graph, &root1_kp, cur_time, far_future, 10);
|
add_root_with_trust(&mut trust_graph, &root1_kp, cur_time, far_future, 0u32);
|
||||||
// opposite
|
// opposite
|
||||||
add_root_with_trust(&mut trust_graph, &root2_kp, cur_time, far_future, 5);
|
add_root_with_trust(&mut trust_graph, &root2_kp, cur_time, far_future, 5u32);
|
||||||
|
|
||||||
// issue trust from root2 to any other peer_id
|
// issue trust from root2 to any other peer_id
|
||||||
let issued_by_root2_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
let issued_by_root2_peer_id = KeyPair::generate_ed25519().get_peer_id();
|
||||||
@ -832,7 +832,7 @@ mod service_tests {
|
|||||||
|
|
||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
let root_peer_id = key_pairs[0].get_peer_id();
|
let root_peer_id = key_pairs[0].get_peer_id();
|
||||||
set_root_peer_id(&mut trust_graph, root_peer_id, 10);
|
add_root_peer_id(&mut trust_graph, root_peer_id, 1);
|
||||||
|
|
||||||
for auth in trusts.iter() {
|
for auth in trusts.iter() {
|
||||||
add_trust_checked(&mut trust_graph, auth.trust.clone(), auth.issuer, cur_time);
|
add_trust_checked(&mut trust_graph, auth.trust.clone(), auth.issuer, cur_time);
|
||||||
@ -862,7 +862,7 @@ mod service_tests {
|
|||||||
|
|
||||||
let cur_time = current_time();
|
let cur_time = current_time();
|
||||||
let root_peer_id = key_pairs[0].get_peer_id();
|
let root_peer_id = key_pairs[0].get_peer_id();
|
||||||
set_root_peer_id(&mut trust_graph, root_peer_id, 10);
|
add_root_peer_id(&mut trust_graph, root_peer_id, 1);
|
||||||
|
|
||||||
for auth in trusts.iter() {
|
for auth in trusts.iter() {
|
||||||
add_trust_checked(&mut trust_graph, auth.trust.clone(), auth.issuer, cur_time);
|
add_trust_checked(&mut trust_graph, auth.trust.clone(), auth.issuer, cur_time);
|
||||||
|
@ -50,8 +50,8 @@ pub struct Revocation {
|
|||||||
impl Revocation {
|
impl Revocation {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
revoked_by: PublicKey,
|
|
||||||
pk: PublicKey,
|
pk: PublicKey,
|
||||||
|
revoked_by: PublicKey,
|
||||||
revoked_at: Duration,
|
revoked_at: Duration,
|
||||||
signature: Signature,
|
signature: Signature,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -69,7 +69,7 @@ impl Revocation {
|
|||||||
let msg = Revocation::signature_bytes(&to_revoke, revoked_at);
|
let msg = Revocation::signature_bytes(&to_revoke, revoked_at);
|
||||||
let signature = revoker.sign(&msg).unwrap();
|
let signature = revoker.sign(&msg).unwrap();
|
||||||
|
|
||||||
Revocation::new(revoker.public(), to_revoke, revoked_at, signature)
|
Revocation::new(to_revoke, revoker.public(), revoked_at, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature_bytes(pk: &PublicKey, revoked_at: Duration) -> Vec<u8> {
|
pub fn signature_bytes(pk: &PublicKey, revoked_at: Duration) -> Vec<u8> {
|
||||||
@ -120,8 +120,8 @@ mod tests {
|
|||||||
|
|
||||||
let duration2 = Duration::new(95, 0);
|
let duration2 = Duration::new(95, 0);
|
||||||
let corrupted_revoke = Revocation::new(
|
let corrupted_revoke = Revocation::new(
|
||||||
revoker.public(),
|
|
||||||
to_revoke.public(),
|
to_revoke.public(),
|
||||||
|
revoker.public(),
|
||||||
duration2,
|
duration2,
|
||||||
revoke.signature,
|
revoke.signature,
|
||||||
);
|
);
|
||||||
|
@ -94,10 +94,6 @@ impl From<TrustGraphError> for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_weight_factor(max_chain_len: u32) -> u32 {
|
|
||||||
MAX_WEIGHT_FACTOR.checked_sub(max_chain_len).unwrap_or(0u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_weight_from_factor(wf: WeightFactor) -> u32 {
|
pub fn get_weight_from_factor(wf: WeightFactor) -> u32 {
|
||||||
2u32.pow(MAX_WEIGHT_FACTOR.saturating_sub(wf))
|
2u32.pow(MAX_WEIGHT_FACTOR.saturating_sub(wf))
|
||||||
}
|
}
|
||||||
@ -111,10 +107,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert new root weight
|
/// Insert new root weight
|
||||||
pub fn set_root(&mut self, pk: PublicKey, max_chain_len: u32) -> Result<(), TrustGraphError> {
|
pub fn add_root_weight_factor(
|
||||||
Ok(self
|
&mut self,
|
||||||
.storage
|
pk: PublicKey,
|
||||||
.set_root_weight_factor(pk.into(), get_weight_factor(max_chain_len))?)
|
weight: WeightFactor,
|
||||||
|
) -> Result<(), TrustGraphError> {
|
||||||
|
Ok(self.storage.add_root_weight_factor(pk.into(), weight)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_trust<T, P>(
|
pub fn add_trust<T, P>(
|
||||||
@ -200,29 +198,6 @@ where
|
|||||||
Ok(max_weight)
|
Ok(max_weight)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the maximum weight of trust for one public key.
|
|
||||||
/// for all chains which contain `issuer`
|
|
||||||
pub fn weight_from<P>(
|
|
||||||
&mut self,
|
|
||||||
issued_for: P,
|
|
||||||
issuer: P,
|
|
||||||
cur_time: Duration,
|
|
||||||
) -> Result<u32, TrustGraphError>
|
|
||||||
where
|
|
||||||
P: Borrow<PublicKey>,
|
|
||||||
{
|
|
||||||
let mut max_weight = 0;
|
|
||||||
|
|
||||||
// get all possible certificates from the given public key to all roots in the graph
|
|
||||||
// which contain `issuer`
|
|
||||||
let certs = self.get_all_certs_from(issued_for, issuer, cur_time)?;
|
|
||||||
if let Some(weight_factor) = self.certificates_weight_factor(certs)? {
|
|
||||||
max_weight = std::cmp::max(max_weight, get_weight_from_factor(weight_factor))
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(max_weight)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate weight from given certificates
|
/// Calculate weight from given certificates
|
||||||
/// Returns None if there is no such public key
|
/// Returns None if there is no such public key
|
||||||
/// or some trust between this key and a root key is revoked.
|
/// or some trust between this key and a root key is revoked.
|
||||||
@ -325,27 +300,6 @@ where
|
|||||||
Ok(terminated_chains)
|
Ok(terminated_chains)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all possible certificates where `issued_for` will be the last element of the chain,
|
|
||||||
/// all certificates contain `issuer`
|
|
||||||
/// and one of the destinations is the root of this chain.
|
|
||||||
pub fn get_all_certs_from<P>(
|
|
||||||
&mut self,
|
|
||||||
issued_for: P,
|
|
||||||
issuer: P,
|
|
||||||
cur_time: Duration,
|
|
||||||
) -> Result<Vec<Certificate>, TrustGraphError>
|
|
||||||
where
|
|
||||||
P: Borrow<PublicKey>,
|
|
||||||
{
|
|
||||||
self.get_all_certs(issued_for, cur_time).map(|c| {
|
|
||||||
c.into_iter()
|
|
||||||
.filter(|cert: &Certificate| {
|
|
||||||
cert.chain.iter().any(|t| t.issued_for.eq(issuer.borrow()))
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get all possible certificates where `issued_for` will be the last element of the chain
|
/// Get all possible certificates where `issued_for` will be the last element of the chain
|
||||||
/// and one of the destinations is the root of this chain.
|
/// and one of the destinations is the root of this chain.
|
||||||
pub fn get_all_certs<P>(
|
pub fn get_all_certs<P>(
|
||||||
@ -390,11 +344,4 @@ where
|
|||||||
|
|
||||||
Ok(self.storage.revoke(revocation)?)
|
Ok(self.storage.revoke(revocation)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_revocations<P>(&self, issued_for: P) -> Result<Vec<Revocation>, TrustGraphError>
|
|
||||||
where
|
|
||||||
P: Borrow<PublicKey>,
|
|
||||||
{
|
|
||||||
Ok(self.storage.get_revocations(issued_for.borrow().as_ref())?)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,7 @@ pub trait Storage {
|
|||||||
fn insert(&mut self, node: TrustRelation) -> Result<(), Self::Error>;
|
fn insert(&mut self, node: TrustRelation) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
fn get_root_weight_factor(&self, pk: &PK) -> Result<Option<WeightFactor>, Self::Error>;
|
fn get_root_weight_factor(&self, pk: &PK) -> Result<Option<WeightFactor>, Self::Error>;
|
||||||
fn set_root_weight_factor(
|
fn add_root_weight_factor(&mut self, pk: PK, weight: WeightFactor) -> Result<(), Self::Error>;
|
||||||
&mut self,
|
|
||||||
pk: PK,
|
|
||||||
weight_factor: WeightFactor,
|
|
||||||
) -> Result<(), Self::Error>;
|
|
||||||
fn root_keys(&self) -> Result<Vec<PK>, Self::Error>;
|
fn root_keys(&self) -> Result<Vec<PK>, Self::Error>;
|
||||||
fn revoke(&mut self, revocation: Revocation) -> Result<(), Self::Error>;
|
fn revoke(&mut self, revocation: Revocation) -> Result<(), Self::Error>;
|
||||||
fn update_auth(&mut self, auth: Auth, cur_time: Duration) -> Result<(), Self::Error>;
|
fn update_auth(&mut self, auth: Auth, cur_time: Duration) -> Result<(), Self::Error>;
|
||||||
|
Reference in New Issue
Block a user