Compare commits

...

4 Commits

24 changed files with 16447 additions and 1595 deletions

6
.cargo/config Normal file
View File

@ -0,0 +1,6 @@
[http]
timeout = 30 # timeout for each HTTP request, in seconds
multiplexing = false # HTTP/2 multiplexing
[net]
retry = 50 # network retries

View File

@ -1,38 +0,0 @@
version: 2.1
orbs:
docker: circleci/docker@1.5.0
jobs:
Build:
docker:
- image: circleci/rust:latest
resource_class: xlarge
environment:
RUST_BACKTRACE: 1
steps:
- checkout
- run: |
sudo bash .github/download_marine.sh
- restore_cache:
keys:
- trust-graph00-{{ checksum "./Cargo.lock" }}
- run: |
rustup target add wasm32-wasi
cargo test --no-fail-fast --release --all-features --
cd ./service
./build.sh
mkdir -p data
cargo test --no-fail-fast --release --all-features -- --test-threads=1
- save_cache:
paths:
- ~/.cargo
- ~/.rustup
key: trust-graph00-{{ checksum "./Cargo.lock" }}
workflows:
version: 2
CircleCI:
jobs:
- Build

View File

@ -3,7 +3,7 @@ set -o pipefail -o errexit -o nounset
set -x set -x
MARINE_RELEASE="https://api.github.com/repos/fluencelabs/marine/releases/latest" MARINE_RELEASE="https://api.github.com/repos/fluencelabs/marine/releases/latest"
OUT_DIR=/usr/local/bin OUT_DIR=~/.bin
# get metadata about release # get metadata about release
curl -s -H "Accept: application/vnd.github.v3+json" $MARINE_RELEASE | curl -s -H "Accept: application/vnd.github.v3+json" $MARINE_RELEASE |

View File

@ -1,5 +1,6 @@
{ {
"template": "${{CHANGELOG}}\n\n${{UNCATEGORIZED}}", "template": "## Changes since ${{FROM_TAG}}\n\n${{CHANGELOG}}\n\n${{UNCATEGORIZED}}",
"pr_template": "- #${{NUMBER}} ${{TITLE}}", "pr_template": "- #${{NUMBER}} ${{TITLE}}",
"empty_template": "- no changes" "empty_template": "## No changes since ${{FROM_TAG}}",
"sort": "DESC"
} }

View File

@ -6,9 +6,9 @@ on:
- "v*" - "v*"
jobs: jobs:
npm-publish: release:
name: "Publish" name: "Publish"
runs-on: ubuntu-latest runs-on: builder
container: rust container: rust
defaults: defaults:
run: run:
@ -22,44 +22,54 @@ jobs:
- name: Set env - name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- run: mkdir -p ~/.bin
- run: echo "~/.bin" >> $GITHUB_PATH
- name: Download jq - name: Download jq
run: | run: |
curl -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 -o /usr/local/bin/jq curl -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 -o ~/.bin/jq
chmod +x /usr/local/bin/jq chmod +x ~/.bin/jq
- name: Download marine - name: Download marine
run: bash $GITHUB_WORKSPACE/.github/download_marine.sh run: bash $GITHUB_WORKSPACE/.github/download_marine.sh
- uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'
- name: Cache npm - name: Cache npm
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-v01-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-v03-${{ hashFiles('**/package-lock.json') }}
restore-keys: | restore-keys: |
${{ runner.os }}-node-v01- ${{ runner.os }}-node-v03-
- uses: actions/setup-node@v2 - uses: actions/setup-node@v2
with: with:
node-version: "15" node-version: "15"
registry-url: "https://registry.npmjs.org" registry-url: "https://registry.npmjs.org"
- uses: actions/cache@v2 - name: Cache cargo
uses: actions/cache@v2
with: with:
path: | path: |
~/.cargo/registry ~/.cargo/registry
~/.cargo/git ~/.cargo/git
~/.cargo/bin
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install toolchain - name: Install Rust
uses: actions-rs/toolchain@v1 working-directory: ./service
with: run: |
profile: minimal rustup toolchain install nightly-2022-01-16-x86_64-unknown-linux-gnu
toolchain: nightly-2022-01-16 rustup default nightly-2022-01-16-x86_64-unknown-linux-gnu
target: wasm32-wasi rustup override set nightly-2022-01-16-x86_64-unknown-linux-gnu
override: true rustup target add wasm32-wasi --toolchain nightly-2022-01-16-x86_64-unknown-linux-gnu
### Build ### Build
- name: trust-graph.wasm - name: Build trust-graph
working-directory: ./service working-directory: ./service
run: ./build.sh run: ./build.sh
@ -69,7 +79,7 @@ jobs:
npm i npm i
npm run build npm run build
- name: Create builtin distribution package - name: Create distribution package
run: | run: |
./builtin-package/package.sh ./builtin-package/package.sh
@ -81,15 +91,15 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
## Publish ### Publish
- name: Release - name: Release to GitHub
id: release id: release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
with: with:
name: trust-graph ${{ env.RELEASE_VERSION }} name: trust-graph ${{ env.RELEASE_VERSION }}
tag_name: ${{ env.RELEASE_VERSION }} tag_name: ${{ env.RELEASE_VERSION }}
files: | files: |
trust-graph.tar.gz ./trust-graph.tar.gz
body: ${{steps.changelog.outputs.changelog}} body: ${{steps.changelog.outputs.changelog}}
draft: false draft: false
prerelease: false prerelease: false
@ -97,10 +107,10 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
### Publish Aqua API ### Publish Aqua API
- name: Publish Aqua API - name: Publish Aqua API to NPM
run: | run: |
npm version ${{ env.RELEASE_VERSION }} --allow-same-version npm version ${{ env.RELEASE_VERSION }}
npm publish --access public npm publish --access public
env: env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@ -109,9 +119,9 @@ jobs:
## Update node-distro repo ## Update node-distro repo
- name: Calculate SHA256 - name: Calculate SHA256
run: | run: |
du -hs trust-graph.tar.gz du -hs trust-graph.tar.gz
echo $(sha256sum trust-graph.tar.gz) echo $(sha256sum trust-graph.tar.gz)
echo "SHA256=$(sha256sum trust-graph.tar.gz | awk '{ print $1 }')" >> $GITHUB_ENV echo "SHA256=$(sha256sum trust-graph.tar.gz | awk '{ print $1 }')" >> $GITHUB_ENV
- name: Get tar.gz URL - name: Get tar.gz URL
id: package-url id: package-url

89
.github/workflows/rust_ci.yml vendored Normal file
View File

@ -0,0 +1,89 @@
name: Rust CI
on:
push:
workflow_dispatch:
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
check:
name: cargo nextest
runs-on: builder
container: rust
defaults:
run:
working-directory: service
shell: bash
steps:
- name: Checkout sources
uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- run: mkdir -p ~/.bin
- run: echo "~/.bin" >> $GITHUB_PATH
- name: Install Rust
working-directory: ./service
run: |
rustup toolchain install nightly-2022-01-16-x86_64-unknown-linux-gnu
rustup default nightly-2022-01-16-x86_64-unknown-linux-gnu
rustup override set nightly-2022-01-16-x86_64-unknown-linux-gnu
rustup target add wasm32-wasi --toolchain nightly-2022-01-16-x86_64-unknown-linux-gnu
- name: Download jq
run: |
curl -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 -o ~/.bin/jq
chmod +x ~/.bin/jq
- name: Download marine
run: bash $GITHUB_WORKSPACE/.github/download_marine.sh
- name: Build
run: ./build.sh
- run: cargo install --locked cargo-nextest --version 0.9.22
- run: cargo nextest run --release --all-features --no-fail-fast --retries 10 --test-threads 10
lints:
name: Lints
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Run cargo fmt
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Run cargo clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: -Z unstable-options --all
continue-on-error: true # do not fail for now

View File

@ -10,8 +10,16 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Get branch
run: |
BRANCH=${GITHUB_REF#refs/*/}
SANITIZED=$(echo "$BRANCH" | sed -e 's/[^a-zA-Z0-9-]/-/g')
echo "BRANCH=$SANITIZED" >> $GITHUB_ENV
- name: Bump version and push tag - name: Bump version and push tag
id: tag_version id: tag_version
uses: mathieudutour/github-tag-action@v5.5 uses: mathieudutour/github-tag-action@v5.5
with: with:
append_to_pre_release_tag: ${{ env.BRANCH }}
github_token: ${{ secrets.PERSONAL_TOKEN }} github_token: ${{ secrets.PERSONAL_TOKEN }}

2
Cargo.lock generated
View File

@ -2672,7 +2672,7 @@ dependencies = [
[[package]] [[package]]
name = "trust-graph-wasm" name = "trust-graph-wasm"
version = "0.3.0" version = "0.3.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",

9337
aqua/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
"*.aqua" "*.aqua"
], ],
"dependencies": { "dependencies": {
"@fluencelabs/aqua-lib": "^0.3.4" "@fluencelabs/aqua-lib": "^0.5.2"
}, },
"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.7.4-322"
} }
} }

View File

@ -11,8 +11,9 @@ service CertOp("op"):
service TrustedComputation("op"): service TrustedComputation("op"):
identity(s: u64) -> u64 identity(s: u64) -> u64
func trusted_computation(node: string) -> ?u64: func trusted_computation(node: string) -> ?u64, ?string:
result: ?u64 result: ?u64
error: ?string
-- on our trusted relay -- on our trusted relay
on HOST_PEER_ID: on HOST_PEER_ID:
-- get all certificates issued for given node by our client's peer id -- get all certificates issued for given node by our client's peer id
@ -20,8 +21,11 @@ func trusted_computation(node: string) -> ?u64:
if certs_result.success: if certs_result.success:
len <- CertOp.array_length(certs_result.certificates) len <- CertOp.array_length(certs_result.certificates)
-- if there is any certificate node is trusted and computation is possible -- if there is any certificate node is trusted and computation is possible
if len != 0: if len != 0:
on node: on node:
result <- TrustedComputation.identity(5) result <- TrustedComputation.identity(5)
else:
<- result error <<- "there is no certs for this peer"
else:
error <<- certs_result.error
<- result, error

View File

@ -1,5 +1,6 @@
module Export
import add_root_trust, add_trust, revoke from "@fluencelabs/trust-graph/trust-graph-api.aqua" import add_root_trust, add_trust, revoke from "@fluencelabs/trust-graph/trust-graph-api.aqua"
export add_root_trust, add_trust, revoke export add_root_trust, add_trust, revoke, timestamp_sec
import Peer from "@fluencelabs/aqua-lib/builtin.aqua" import Peer from "@fluencelabs/aqua-lib/builtin.aqua"
alias PeerId: string alias PeerId: string

View File

@ -14,10 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
import {trusted_computation} from "./generated/computation"; 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, FluencePeer, KeyPair } from "@fluencelabs/fluence";
import {krasnodar, Node, testNet, stage} from "@fluencelabs/fluence-network-environment"; import { krasnodar, Node, testNet, stage } from "@fluencelabs/fluence-network-environment";
import assert from "assert"; import assert from "assert";
const bs58 = require('bs58'); const bs58 = require('bs58');
@ -42,7 +42,7 @@ let local: Node[] = [
async function revoke_all(relay: string, revoked_by: string) { async function revoke_all(relay: string, revoked_by: string) {
for (var node of local) { for (var node of local) {
let error = await tg.revoke(relay, revoked_by, node.peerId); let error = await tg.revoke(relay, revoked_by, node.peerId);
if (error === null) { if (error !== null) {
console.log(error) console.log(error)
} }
} }
@ -51,7 +51,7 @@ async function add_root(relay: string, peer_id: string) {
let current_time = await tg.timestamp_sec(); let current_time = await tg.timestamp_sec();
let far_future = current_time + 9999999; let far_future = current_time + 9999999;
let error = await tg.add_root_trust(relay, peer_id, 2, far_future); let error = await tg.add_root_trust(relay, peer_id, 2, far_future);
if (error === null) { if (error !== null) {
console.log(error) console.log(error)
} }
} }
@ -75,12 +75,12 @@ async function revoke_checked(relay: string, revoked_by: string, revoked_peer_id
} }
async function exec_trusted_computation(node: string) { async function exec_trusted_computation(node: string) {
let result = await trusted_computation(node) let [result, error] = await trusted_computation(node)
if (result !== null) { if (result !== null) {
console.log("📗 Trusted computation on node %s successful, result is %s", node, result) console.log("📗 Trusted computation on node %s successful, result is %s", node, result)
} else { } else {
console.log("📕 Trusted computation on node %s failed", node) console.log("📕 Trusted computation on node %s failed, error:", node, error)
} }
} }
@ -92,7 +92,7 @@ async function main() {
let builtins_keypair = await KeyPair.fromEd25519SK(sk); let builtins_keypair = await KeyPair.fromEd25519SK(sk);
let relay = local[0]; let relay = local[0];
await Fluence.start({ connectTo: relay, 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,

8302
example/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,14 +13,14 @@
"author": "Fluence Labs", "author": "Fluence Labs",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fluencelabs/aqua": "^0.5.2-257", "@fluencelabs/aqua-lib": "^0.5.2",
"@fluencelabs/aqua-lib": "^0.3.4", "@fluencelabs/fluence": "^0.23.0",
"@fluencelabs/fluence": "^0.18.0",
"@fluencelabs/fluence-network-environment": "^1.0.10", "@fluencelabs/fluence-network-environment": "^1.0.10",
"@fluencelabs/trust-graph": "file:../aqua", "@fluencelabs/trust-graph": "3.0.2",
"bs58": "^4.0.1" "bs58": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^4.5.2" "typescript": "^4.5.2",
"@fluencelabs/aqua": "^0.7.4-325"
} }
} }

View File

@ -165,7 +165,7 @@ impl TryFrom<libp2p_core::PeerId> for PublicKey {
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(as_public_key(&peer_id) Ok(as_public_key(&peer_id)
.ok_or(DecodingError::PublicKeyNotInlined(peer_id.to_base58()))? .ok_or_else(|| DecodingError::PublicKeyNotInlined(peer_id.to_base58()))?
.into()) .into())
} }
} }
@ -177,7 +177,9 @@ fn as_public_key(peer_id: &PeerId) -> Option<libp2p_core::PublicKey> {
let mhash = peer_id.as_ref(); let mhash = peer_id.as_ref();
match multihash::Code::try_from(mhash.code()) { match multihash::Code::try_from(mhash.code()) {
Ok(multihash::Code::Identity) => libp2p_core::PublicKey::from_protobuf_encoding(mhash.digest()).ok(), Ok(multihash::Code::Identity) => {
libp2p_core::PublicKey::from_protobuf_encoding(mhash.digest()).ok()
}
_ => None, _ => None,
} }
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "trust-graph-wasm" name = "trust-graph-wasm"
version = "0.3.0" version = "0.3.1"
authors = ["Fluence Labs"] authors = ["Fluence Labs"]
edition = "2018" edition = "2018"
description = "trust graph wasm" description = "trust graph wasm"

View File

@ -40,7 +40,7 @@ pub struct Certificate {
impl From<trust_graph::Certificate> for Certificate { impl From<trust_graph::Certificate> for Certificate {
fn from(c: trust_graph::Certificate) -> Self { fn from(c: trust_graph::Certificate) -> Self {
let chain: Vec<Trust> = c.chain.into_iter().map(|t| t.into()).collect(); let chain: Vec<Trust> = c.chain.into_iter().map(|t| t.into()).collect();
return Certificate { chain }; Certificate { chain }
} }
} }
@ -51,10 +51,10 @@ impl TryFrom<Certificate> for trust_graph::Certificate {
let chain: Result<Vec<trust_graph::Trust>, DtoConversionError> = c let chain: Result<Vec<trust_graph::Trust>, DtoConversionError> = c
.chain .chain
.into_iter() .into_iter()
.map(|t| trust_graph::Trust::try_from(t)) .map(trust_graph::Trust::try_from)
.collect(); .collect();
let chain = chain?; let chain = chain?;
return Ok(trust_graph::Certificate { chain }); Ok(trust_graph::Certificate { chain })
} }
} }
@ -85,12 +85,12 @@ impl TryFrom<Trust> for trust_graph::Trust {
let signature = Signature::from_bytes(KeyFormat::from_str(&t.sig_type)?, signature); let signature = Signature::from_bytes(KeyFormat::from_str(&t.sig_type)?, signature);
let expires_at = Duration::from_secs(t.expires_at); let expires_at = Duration::from_secs(t.expires_at);
let issued_at = Duration::from_secs(t.issued_at); let issued_at = Duration::from_secs(t.issued_at);
return Ok(trust_graph::Trust { Ok(trust_graph::Trust {
issued_for, issued_for,
expires_at, expires_at,
signature, signature,
issued_at, issued_at,
}); })
} }
} }
@ -101,13 +101,13 @@ impl From<trust_graph::Trust> for Trust {
let signature = bs58::encode(raw_signature.bytes).into_string(); let signature = bs58::encode(raw_signature.bytes).into_string();
let expires_at = t.expires_at.as_secs(); let expires_at = t.expires_at.as_secs();
let issued_at = t.issued_at.as_secs(); let issued_at = t.issued_at.as_secs();
return Trust { Trust {
issued_for, issued_for,
expires_at, expires_at,
signature, signature,
sig_type: raw_signature.sig_type.into(), sig_type: raw_signature.sig_type.into(),
issued_at, issued_at,
}; }
} }
} }
@ -142,12 +142,12 @@ impl TryFrom<Revocation> for trust_graph::Revocation {
let signature = bs58::decode(&r.signature).into_vec()?; let signature = bs58::decode(&r.signature).into_vec()?;
let signature = Signature::from_bytes(KeyFormat::from_str(&r.sig_type)?, signature); let signature = Signature::from_bytes(KeyFormat::from_str(&r.sig_type)?, signature);
let revoked_at = Duration::from_secs(r.revoked_at); let revoked_at = Duration::from_secs(r.revoked_at);
return Ok(trust_graph::Revocation { Ok(trust_graph::Revocation {
pk: revoked_pk, pk: revoked_pk,
revoked_at, revoked_at,
revoked_by: revoked_by_pk, revoked_by: revoked_by_pk,
signature, signature,
}); })
} }
} }
@ -158,12 +158,12 @@ impl From<trust_graph::Revocation> for Revocation {
let raw_signature = r.signature.get_raw_signature(); let raw_signature = r.signature.get_raw_signature();
let signature = bs58::encode(raw_signature.bytes).into_string(); let signature = bs58::encode(raw_signature.bytes).into_string();
let revoked_at = r.revoked_at.as_secs(); let revoked_at = r.revoked_at.as_secs();
return Revocation { Revocation {
revoked_peer_id, revoked_peer_id,
revoked_at, revoked_at,
signature, signature,
sig_type: raw_signature.sig_type.into(), sig_type: raw_signature.sig_type.into(),
revoked_by, revoked_by,
}; }
} }
} }

View File

@ -13,10 +13,31 @@ mod results;
mod service_api; mod service_api;
mod storage_impl; mod storage_impl;
mod tests; mod tests;
/*
_initialize function that calls __wasm_call_ctors is required to mitigade memory leak
that is described in https://github.com/WebAssembly/wasi-libc/issues/298
In short, without this code rust wraps every export function
with __wasm_call_ctors/__wasm_call_dtors calls. This causes memory leaks. When compiler sees
an explicit call to __wasm_call_ctors in _initialize function, it disables export wrapping.
TODO: remove when updating to marine-rs-sdk with fix
*/
extern "C" {
pub fn __wasm_call_ctors();
}
#[no_mangle]
fn _initialize() {
unsafe {
__wasm_call_ctors();
}
}
//------------------------------
pub static TRUSTED_TIMESTAMP: (&str, &str) = ("peer", "timestamp_sec"); pub static TRUSTED_TIMESTAMP: (&str, &str) = ("peer", "timestamp_sec");
pub fn main() { pub fn main() {
_initialize(); // As __wasm_call_ctors still does necessary work, we call it at the start of the module
WasmLoggerBuilder::new() WasmLoggerBuilder::new()
.with_log_level(log::LevelFilter::Trace) .with_log_level(log::LevelFilter::Trace)
.build() .build()

View File

@ -27,10 +27,10 @@ fn set_root(peer_id: String, max_chain_len: u32) -> SetRootResult {
}) })
.into() .into()
} else { } else {
return SetRootResult { SetRootResult {
success: false, success: false,
error: ServiceError::NotOwner.to_string(), error: ServiceError::NotOwner.to_string(),
}; }
} }
} }
@ -98,7 +98,7 @@ fn get_all_certs(issued_for: String, timestamp_sec: u64) -> AllCertsResult {
fn get_all_certs_from(issued_for: String, issuer: String, timestamp_sec: u64) -> AllCertsResult { fn get_all_certs_from(issued_for: String, 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, 2)?;
get_certs_from(tg, issued_for, issuer, timestamp_sec) get_certs_from(tg, issued_for, issuer, timestamp_sec)
}) })
.into() .into()

View File

@ -272,7 +272,7 @@ impl Storage for SQLiteStorage {
statement.bind(6, &Value::Binary(relation.signature().encode()))?; statement.bind(6, &Value::Binary(relation.signature().encode()))?;
statement.next()?; statement.next()?;
Ok({}) Ok(())
} }
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> {
@ -309,7 +309,7 @@ impl Storage for SQLiteStorage {
])?; ])?;
cursor.next()?; cursor.next()?;
Ok({}) Ok(())
} }
fn root_keys(&self) -> Result<Vec<PK>, Self::Error> { fn root_keys(&self) -> Result<Vec<PK>, Self::Error> {

View File

@ -887,4 +887,40 @@ mod service_tests {
assert_eq!(*trust, trusts[i].trust); assert_eq!(*trust, trusts[i].trust);
} }
} }
#[test]
fn test_get_all_cert_from() {
let mut trust_graph = ServiceInterface::new();
clear_env();
let (key_pairs, trusts) =
generate_trust_chain_with_len(&mut trust_graph, 5, HashMap::new());
let cur_time = current_time();
let root_peer_id = key_pairs[0].get_peer_id();
set_root_peer_id(&mut trust_graph, root_peer_id, 10);
for auth in trusts.iter() {
add_trust_checked(&mut trust_graph, auth.trust.clone(), auth.issuer, cur_time);
}
let cp = get_correct_timestamp_cp_with_host_id(
2,
key_pairs.last().unwrap().get_peer_id().to_base58(),
);
let certs = trust_graph.get_all_certs_from_cp(
key_pairs[4].get_peer_id().to_base58(),
key_pairs[3].get_peer_id().to_base58(),
cur_time,
cp,
);
assert!(certs.success, "{}", certs.error);
let certs = certs.certificates;
assert_eq!(certs.len(), 1);
assert_eq!(certs[0].chain.len(), 5);
for (i, trust) in certs[0].chain.iter().enumerate() {
assert_eq!(*trust, trusts[i].trust);
}
}
} }

View File

@ -74,14 +74,26 @@ impl Certificate {
Self { chain } Self { chain }
} }
pub fn new_from_root_trust(root_trust: Trust, issued_trust: Trust, cur_time: Duration) -> Result<Self, CertificateError> { pub fn new_from_root_trust(
root_trust: Trust,
issued_trust: Trust,
cur_time: Duration,
) -> Result<Self, CertificateError> {
Trust::verify(&root_trust, &root_trust.issued_for, cur_time).map_err(MalformedRoot)?; Trust::verify(&root_trust, &root_trust.issued_for, cur_time).map_err(MalformedRoot)?;
Trust::verify(&issued_trust, &root_trust.issued_for, cur_time).map_err(|e| VerificationError(1, e))?; Trust::verify(&issued_trust, &root_trust.issued_for, cur_time)
.map_err(|e| VerificationError(1, e))?;
Ok(Self { chain: vec![root_trust, issued_trust] }) Ok(Self {
chain: vec![root_trust, issued_trust],
})
} }
pub fn issue_with_trust(issued_by: PublicKey, trust: Trust, extend_cert: &Certificate, cur_time: Duration) -> Result<Self, CertificateError> { pub fn issue_with_trust(
issued_by: PublicKey,
trust: Trust,
extend_cert: &Certificate,
cur_time: Duration,
) -> Result<Self, CertificateError> {
if trust.expires_at.lt(&trust.issued_at) { if trust.expires_at.lt(&trust.issued_at) {
return Err(ExpirationError { return Err(ExpirationError {
expires_at: format!("{:?}", trust.expires_at), expires_at: format!("{:?}", trust.expires_at),
@ -89,7 +101,11 @@ impl Certificate {
}); });
} }
Certificate::verify(extend_cert, &[extend_cert.chain[0].issued_for.clone()], cur_time)?; Certificate::verify(
extend_cert,
&[extend_cert.chain[0].issued_for.clone()],
cur_time,
)?;
// check if `issued_by` is allowed to issue a certificate (i.e., theres a trust for it in a chain) // check if `issued_by` is allowed to issue a certificate (i.e., theres a trust for it in a chain)
let mut previous_trust_num: i32 = -1; let mut previous_trust_num: i32 = -1;
for pk_id in 0..extend_cert.chain.len() { for pk_id in 0..extend_cert.chain.len() {
@ -114,7 +130,6 @@ impl Certificate {
Ok(Self { chain: new_chain }) Ok(Self { chain: new_chain })
} }
/// Creates new certificate with root trust (self-signed public key) from a key pair. /// Creates new certificate with root trust (self-signed public key) from a key pair.
#[allow(dead_code)] #[allow(dead_code)]
pub fn issue_root( pub fn issue_root(
@ -151,7 +166,11 @@ impl Certificate {
} }
// first, verify given certificate // first, verify given certificate
Certificate::verify(extend_cert, &[extend_cert.chain[0].issued_for.clone()], cur_time)?; Certificate::verify(
extend_cert,
&[extend_cert.chain[0].issued_for.clone()],
cur_time,
)?;
let issued_by_pk = issued_by.public(); let issued_by_pk = issued_by.public();
@ -309,7 +328,7 @@ impl FromStr for Certificate {
str_lines[i + 2], str_lines[i + 2],
str_lines[i + 3], str_lines[i + 3],
) )
.map_err(|e| DecodeTrustError(i, e))?; .map_err(|e| DecodeTrustError(i, e))?;
trusts.push(trust); trusts.push(trust);
} }
@ -353,7 +372,7 @@ mod tests {
cur_time, cur_time,
cur_time, cur_time,
) )
.unwrap(); .unwrap();
let serialized = new_cert.to_string(); let serialized = new_cert.to_string();
let deserialized = Certificate::from_str(&serialized); let deserialized = Certificate::from_str(&serialized);
@ -380,7 +399,7 @@ mod tests {
cur_time, cur_time,
cur_time, cur_time,
) )
.unwrap(); .unwrap();
let serialized = new_cert.encode(); let serialized = new_cert.encode();
let deserialized = Certificate::decode(serialized.as_slice()); let deserialized = Certificate::decode(serialized.as_slice());
@ -468,7 +487,7 @@ mod tests {
cur_time.checked_sub(one_minute()).unwrap(), cur_time.checked_sub(one_minute()).unwrap(),
cur_time, cur_time,
) )
.unwrap(); .unwrap();
assert!(Certificate::verify(&new_cert, &trusted_roots, cur_time).is_err()); assert!(Certificate::verify(&new_cert, &trusted_roots, cur_time).is_err());
} }
@ -490,7 +509,7 @@ mod tests {
cur_time, cur_time,
cur_time, cur_time,
) )
.unwrap(); .unwrap();
let new_cert = Certificate::issue( let new_cert = Certificate::issue(
&third_kp, &third_kp,
fourth_kp.public(), fourth_kp.public(),
@ -528,7 +547,7 @@ mod tests {
cur_time, cur_time,
cur_time, cur_time,
) )
.unwrap(); .unwrap();
let new_cert = Certificate::issue( let new_cert = Certificate::issue(
&second_kp, &second_kp,
fourth_kp.public(), fourth_kp.public(),

View File

@ -95,7 +95,7 @@ impl From<TrustGraphError> for String {
} }
fn get_weight_factor(max_chain_len: u32) -> u32 { fn get_weight_factor(max_chain_len: u32) -> u32 {
MAX_WEIGHT_FACTOR.checked_sub(max_chain_len).unwrap_or(0u32) MAX_WEIGHT_FACTOR.saturating_sub(max_chain_len)
} }
pub fn get_weight_from_factor(wf: WeightFactor) -> u32 { pub fn get_weight_from_factor(wf: WeightFactor) -> u32 {