Compare commits

...

57 Commits

Author SHA1 Message Date
4e7a9b5a77 version update 2023-12-18 17:13:16 +03:00
e5b8a9c011 remove std feature, add u64_backend feature 2023-08-23 10:47:52 +02:00
f3bce3023a make ed25519-dalek compilable 2023-08-22 18:24:55 +02:00
ee63de8c71 remove ring dep 2023-08-10 21:10:45 +04:00
d3d26717bd Patched libp2p-identity version that has feature-gated rand 2023-08-10 13:44:12 +04:00
08b1879de9 Turn some unreachable to unimplemented
They have become reachable after dropping some variants' support.
2023-08-10 13:23:46 +04:00
9a006f1f35 Make rand a feature-gated dep 2023-08-10 13:23:25 +04:00
35ea650928 clean some remnants 2023-08-09 20:17:16 +04:00
6630e40d8a Remove stale test keypair data 2023-08-09 13:21:28 +04:00
3f37ed0920 feat(keypair)!: keypair ed25519 only
We do not use RSA and Secp256k1, and they limit portability.  This pull
requests removes their support, keeping, however, the enum-based
implementation of many `fluence-keypair` types.
2023-08-08 19:17:29 +04:00
d378fe2509 chore: Do not publish package (#124)
Do not publish package
2023-08-02 14:21:16 +03:00
80bf4aa4ff chore: release master (#117) 2023-07-04 20:33:47 +03:00
80757e6352 chore(deps): update dependency @fluencelabs/aqua to ^0.10.0 (#71)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-04 19:51:30 +03:00
f2c3b2a13c fix(deps): update dependency @fluencelabs/trust-graph to v3.1.2 (#69)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-04 19:51:01 +03:00
4f657f9dae fix(deps): update dependency @fluencelabs/aqua-lib to ^0.6.0 (#67)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-04 19:49:20 +03:00
725d3f8f48 fix(deps): update rust crate marine-rs-sdk-test to 0.10.0 (#106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-04 19:48:56 +03:00
1fb02e4827 chore(deps): update rust crate lazy_static to 1.4 (#108)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-04 19:48:12 +03:00
a37bda37a2 chore(deps): update rust crate built to 0.6.0 (#115)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-04 19:47:55 +03:00
ee330a715a fix(keypair): deserialize libp2p keypair from secret key (#116)
* fix: Ed25519 keypair

* Update keypair/src/key_pair.rs

Co-authored-by: folex <0xdxdy@gmail.com>

---------

Co-authored-by: folex <0xdxdy@gmail.com>
2023-07-04 19:47:26 +03:00
c22eab38c1 chore: release master (#113) 2023-06-30 11:15:20 +03:00
3692d6898d chore: Revert "chore: release master (#111)" (#114)
Revert "chore: release master (#111)"

This reverts commit 3a5f23741f.
2023-06-30 11:03:02 +03:00
3a5f23741f chore: release master (#111) 2023-06-29 20:35:37 +03:00
b10991501d fix: changed build.sh for test ci & release (#112) 2023-06-29 11:28:41 -06:00
d80a43bcff revert: release master (#110)
Revert "chore: release master (#104)"

This reverts commit a7ea41ed4d.
2023-06-29 19:51:42 +03:00
a7ea41ed4d chore: release master (#104) 2023-06-29 19:31:25 +03:00
d04120bacf feat: update libp2p identity (#109) 2023-06-29 19:21:14 +03:00
3ba3855892 feat: add distro crate [fixes NET-463] (#93)
* add distro crate

---------

Co-authored-by: Anatoly Laskaris <github_me@nahsi.dev>
2023-06-20 14:07:53 +02:00
f7ef0f8da0 fix(keypair): update description (#105) 2023-05-16 10:40:47 -06:00
2001f900fa fix(deps): update rust crate derivative to 2.2.0 (#88)
fix(deps): update rust crate derivative to 2.2.0

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-16 10:26:55 -06:00
412b8ba725 chore: update libp2p (#103)
deps: update libp2p
2023-05-16 19:24:03 +03:00
a7abe87c09 chore: release master (#102) 2023-05-09 17:59:08 +04:00
1a26a6809e feat: dummy to trigger release (#101) 2023-05-09 17:46:41 +04:00
93161afe0c feat: fix builtin package path (#100) 2023-05-09 16:37:48 +03:00
11fd2de7b6 chore: release master (#99) 2023-05-09 16:55:01 +04:00
a8fdb4472e feat: fix trust-graph package (#98) 2023-05-09 15:25:49 +04:00
56d0ea27bd chore: Fix update in rust-peer-distro (#97)
Fix update in rust-peer-distro
2023-05-08 18:38:53 +03:00
d0c6c62ca4 chore: release master (#96) 2023-05-08 18:21:23 +04:00
b6df3fe548 feat: dummy change for release (#95) 2023-05-08 17:08:41 +03:00
a747b9cc75 feat(builtin-package): use new blueprint (#94) 2023-05-08 16:48:39 +03:00
d567848cba chore: release master (#92) 2023-05-03 16:58:12 +04:00
9b942eacca feat(keypair): Make KeyFormat more convenient (#91)
* feat(keypair): Make `KeyFormat` more convenient

1. Make `KeyFormat` implement `Debug`, `Clone` and `Eq`.
2. Add `KeyPair::key_format(&self) -> KeyFormat` method.
2023-05-03 02:48:42 +07:00
c85fb16de3 chore: Fix build script (#90)
Fix build script
2023-04-18 16:42:51 +03:00
97ce5bbac7 chore(release-please): Fix publishing (#89)
Fix typo
2023-04-18 11:24:24 +03:00
864b7f5c13 chore: release master (#83) 2023-04-13 16:11:54 +03:00
da38a41ba7 fix(deps): Add trust-graph to workspace and bump sqlite-wasm version (#87)
* Add trust-graph to workspace

* Bump sqlite lite version

* Fix link
2023-04-13 15:03:08 +03:00
7493eed216 chore: skip cargo-workspace merge in release-please (#86)
Fix
2023-04-13 13:59:44 +03:00
e9399b7d0c chore: Move trust-graph to subdir (#85)
* Fix?

* Move trust-grap to subdir

* fix quickcheck update

* fix fmt

* fix service tests

* use marine 0.9.1

---------

Co-authored-by: Maria Kuklina <maria@fluence.one>
Co-authored-by: Valery Antopol <valery.antopol@gmail.com>
2023-04-13 13:55:35 +03:00
81eb924476 chore: Try workaround for release-please merge issue (#84) 2023-04-12 17:06:28 +03:00
fe902acc50 update aqua-lib (#81) 2023-04-12 15:22:47 +02:00
f5994b33d1 chore: Use setup-marine action (#78) 2023-03-20 12:19:48 +04:00
554bb60256 chore: release master (#63)
* chore: release master

* chore: bump fluence-keypair to 0.10.0 manually

---------

Co-authored-by: folex <0xdxdy@gmail.com>
2023-03-15 19:34:08 -03:00
080503dcfa feat(deps)!: update libp2p to 0.39.1 and other deps (#77)
Co-authored-by: folex <0xdxdy@gmail.com>
2023-03-15 19:17:21 -03:00
757145fffc chore: Add release-please, renovate (#61) 2023-01-30 15:32:57 +04:00
8e58f56190 chore: Update CI and fix clippy warnings [fixes FLU-251] (#62)
* Add release-please and renovate

* Update ci

* Revert "Add release-please and renovate"

This reverts commit a37a4e2a59.

* Allow unnecessary_lazy_evaluations
2023-01-30 18:43:16 +08:00
664552d4f9 chore: update cargo dependencies (#55) 2023-01-30 14:42:12 +04:00
c717e4dc73 chore(fluence-keypair): increment fluence-keypair version to 0.9.0 (#60)
* Increment version

* Increment version

* Increment version
2023-01-27 17:09:12 +03:00
015422efcc Update libp2p-core to 0.38 (#51) 2023-01-27 16:43:47 +03:00
69 changed files with 6593 additions and 5726 deletions

3
.github/actionlint.yaml vendored Normal file
View File

@ -0,0 +1,3 @@
self-hosted-runner:
labels:
- builder

View File

@ -1,14 +0,0 @@
#!/bin/bash
set -o pipefail -o errexit -o nounset
set -x
MARINE_RELEASE="https://api.github.com/repos/fluencelabs/marine/releases/latest"
OUT_DIR=~/.bin
# get metadata about release
curl -s -H "Accept: application/vnd.github.v3+json" $MARINE_RELEASE |
# extract url and name for asset with name "marine"
# also append $OUT_DIR to each name so file is saved to $OUT_DIR
jq -r ".assets | .[] | select(.name == \"marine\") | \"\(.browser_download_url) $OUT_DIR/\(.name)\"" |
# download assets
xargs -n2 bash -c 'curl -L $0 -o $1 && chmod +x $1'

40
.github/release-please/config.json vendored Normal file
View File

@ -0,0 +1,40 @@
{
"boostrap-sha": "015422efcce41530a6cd84a25091598bc459d2e6",
"release-type": "rust",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"plugins": [
{
"type": "cargo-workspace",
"merge": false
},
{
"type": "linked-versions",
"groupName": "trust-graph, wasm and api",
"components": [
"trust-graph",
"trust-graph-api",
"trust-graph-wasm",
"distro"
]
}
],
"packages": {
"trust-graph": {
"component": "trust-graph"
},
"aqua": {
"release-type": "node",
"component": "trust-graph-api"
},
"service": {
"component": "trust-graph-wasm"
},
"keypair": {
"component": "keypair"
},
"distro": {
"component": "distro"
}
}
}

7
.github/release-please/manifest.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"trust-graph": "0.4.7",
"aqua": "0.4.7",
"service": "0.4.7",
"keypair": "0.10.3",
"distro": "0.4.7"
}

38
.github/renovate.json vendored Normal file
View File

@ -0,0 +1,38 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
":semanticCommitTypeAll(chore)"
],
"enabledManagers": ["cargo", "npm", "github-actions", "pip_requirements"],
"rangeStrategy": "pin",
"schedule": "every weekend",
"packageRules": [
{
"matchManagers": ["cargo", "npm"],
"matchPackagePatterns": [
"@fluencelabs/.*",
"fluence-.*",
"marine-.*"
],
"semanticCommitType": "fix",
"semanticCommitScope": "deps",
"schedule": "at any time"
},
{
"matchDepTypes": ["devDependencies"],
"prPriority": -1,
"semanticCommitType": "chore",
"semanticCommitScope": "deps"
},
{
"matchUpdateTypes": ["major"],
"prConcurrentLimit": 1
},
{
"matchManagers": ["github-actions"],
"groupName": "all github-actions",
"prPriority": -1
}
]
}

View File

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

35
.github/workflows/lint.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: lint
on:
pull_request:
types:
- opened
- edited
- synchronize
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
pr:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
reviewdog:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Lint actions
uses: reviewdog/action-actionlint@v1
env:
SHELLCHECK_OPTS: "-e SC2086 -e SC2207 -e SC2128"
with:
reporter: github-pr-check
fail_on_error: true

View File

@ -1,134 +1,153 @@
name: "publish-release"
name: "release"
on:
push:
tags:
- "v*"
branches:
- "master"
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
jobs:
release:
name: "Publish"
runs-on: builder
release-please:
runs-on: ubuntu-latest
outputs:
releases-created: ${{ steps.release.outputs['releases_created'] }}
trust-graph-api-release-created: ${{ steps.release.outputs['aqua--release_created'] }}
trust-graph-release-created: ${{ steps.release.outputs['trust-graph--release_created'] }}
trust-graph-tag-name: ${{ steps.release.outputs['trust-graph--tag_name'] }}
trust-graph-version: ${{ steps.release.outputs['trust-graph--version'] }}
steps:
### Setup
- name: Checkout repository
- name: Run release-please
id: release
uses: google-github-actions/release-please-action@v3
with:
token: ${{ secrets.FLUENCEBOT_RELEASE_PLEASE_PAT }}
command: manifest
config-file: .github/release-please/config.json
manifest-file: .github/release-please/manifest.json
- name: Show output from release-please
if: steps.release.outputs.releases_created
env:
RELEASE_PLEASE_OUTPUT: ${{ toJSON(steps.release.outputs) }}
run: echo "${RELEASE_PLEASE_OUTPUT}" | jq
publish:
runs-on: builder
needs: release-please
if: needs.release-please.outputs.releases-created
permissions:
contents: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- uses: actions/setup-node@v3
- name: Import secrets
uses: hashicorp/vault-action@v2.4.3
with:
node-version: "15"
registry-url: "https://registry.npmjs.org"
cache: npm
cache-dependency-path: "aqua/package-lock.json"
- run: mkdir -p ~/.bin
- run: echo "~/.bin" >> $GITHUB_PATH
url: https://vault.fluence.dev
path: jwt/github
role: ci
method: jwt
jwtGithubAudience: "https://github.com/fluencelabs"
jwtTtl: 300
exportToken: false
secrets: |
kv/npmjs/fluencebot token | NODE_AUTH_TOKEN ;
kv/crates.io/fluencebot token | CARGO_REGISTRY_TOKEN
- name: Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Download marine
run: bash $GITHUB_WORKSPACE/.github/download_marine.sh
- name: Setup marine
uses: fluencelabs/setup-marine@v1
- name: Build trust-graph
working-directory: ./service
- name: Build
run: ./build.sh
- name: Check Aqua compiles
working-directory: ./aqua
- name: Install cargo-workspaces
uses: baptiste0928/cargo-install@v1.3.0
with:
crate: cargo-workspaces
- name: Publish to crates.io
run: |
npm i
npm run build
cargo ws publish \
--no-git-commit \
--allow-dirty \
--from-git \
--skip-published \
--yes
- name: Create distribution package
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: "16"
registry-url: "https://registry.npmjs.org"
cache-dependency-path: "aqua/package-lock.json"
cache: "npm"
- run: npm i
working-directory: aqua
- run: npm run build
working-directory: aqua
- name: Publish to NPM registry
if: needs.release-please.outputs.trust-graph-api-release-created
run: npm publish --access public
working-directory: aqua
slack:
if: always()
name: "Notify"
runs-on: ubuntu-latest
needs:
- release-please
- publish
permissions:
contents: read
id-token: write
steps:
- uses: lwhiteley/dependent-jobs-result-check@v1
id: status
with:
statuses: failure
dependencies: ${{ toJSON(needs) }}
- name: Log output
run: |
./builtin-package/package.sh
echo "statuses:" "${{ steps.status.outputs.statuses }}"
echo "jobs:" "${{ steps.status.outputs.jobs }}"
echo "found any?:" "${{ steps.status.outputs.found }}"
- name: Build Changelog
id: changelog
uses: mikepenz/release-changelog-builder-action@v1
- name: Import secrets
uses: hashicorp/vault-action@v2.4.3
with:
configuration: ".github/workflows/changelog_config.json"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
url: https://vault.fluence.dev
path: jwt/github
role: ci
method: jwt
jwtGithubAudience: "https://github.com/fluencelabs"
jwtTtl: 300
exportToken: false
secrets: |
kv/slack/release-please webhook | SLACK_WEBHOOK_URL
### Publish
- name: Release to GitHub
id: release
uses: softprops/action-gh-release@v1
- uses: ravsamhq/notify-slack-action@v2
if: steps.status.outputs.found == 'true'
with:
name: trust-graph ${{ env.RELEASE_VERSION }}
tag_name: ${{ env.RELEASE_VERSION }}
files: |
./trust-graph.tar.gz
body: ${{steps.changelog.outputs.changelog}}
draft: false
prerelease: false
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
### Publish Aqua API
- name: Publish Aqua API to NPM
run: |
npm version ${{ env.RELEASE_VERSION }}
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
working-directory: ./aqua
## Update node-distro repo
- name: Calculate SHA256
run: |
du -hs trust-graph.tar.gz
echo $(sha256sum trust-graph.tar.gz)
echo "SHA256=$(sha256sum trust-graph.tar.gz | awk '{ print $1 }')" >> $GITHUB_ENV
- name: Get tar.gz URL
id: package-url
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-encoding: string
script: |
try {
let assets = await github.repos.listReleaseAssets({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: "${{ steps.release.outputs.id }}",
});
console.dir(assets);
let package = assets.data.find((a) => a.name === 'trust-graph.tar.gz');
let url = package.browser_download_url;
console.log("URL: " + url);
return url;
} catch (e) {
console.log("Err: " + e);
throw e;
}
- name: Update version in node-distro repo
uses: benc-uk/workflow-dispatch@v1
with:
workflow: update_service
repo: fluencelabs/node-distro
ref: 'main'
token: ${{ secrets.PERSONAL_TOKEN }}
inputs: '{
"name": "trust-graph",
"version": "${{ env.RELEASE_VERSION }}",
"url": "${{ steps.package-url.outputs.result }}",
"sha256": "${{ env.SHA256 }}"
}'
- name: Log notice
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
console.dir(core);
core.info("trust-graph was updated to ${{ env.RELEASE_VERSION }} in node-distro repo");
status: "failure"
notification_title: "*{workflow}* has {status_message}"
message_format: "${{ steps.status.outputs.jobs }} {status_message} in <{repo_url}|{repo}>"
footer: "<{run_url}>"

35
.github/workflows/run-tests.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: Run tests
on:
pull_request:
paths-ignore:
- "**.md"
push:
branches:
- "master"
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
trust-graph:
uses: ./.github/workflows/tests.yml
lints:
name: lints
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Setup rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Run cargo fmt
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check

View File

@ -1,89 +0,0 @@
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
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 toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
- name: Add wasm32-wasi target
run: rustup target add wasm32-wasi
- 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

@ -1,25 +0,0 @@
name: "tag"
on:
workflow_dispatch:
jobs:
tag:
name: "Tag"
runs-on: "ubuntu-latest"
steps:
- 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
id: tag_version
uses: mathieudutour/github-tag-action@v5.5
with:
append_to_pre_release_tag: ${{ env.BRANCH }}
github_token: ${{ secrets.PERSONAL_TOKEN }}

59
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,59 @@
name: Run tests with workflow_call
on:
workflow_call:
jobs:
trust-graph:
name: "cargo nextest"
runs-on: builder
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Setup marine
uses: fluencelabs/setup-marine@v1
- name: Build
run: ./build.sh
- name: Run cargo clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: -Z unstable-options --all
- name: Install cargo-nextest
uses: baptiste0928/cargo-install@v1.3.0
with:
crate: cargo-nextest
version: 0.9.22
- name: Run cargo nextest
env:
NEXTEST_RETRIES: 10
NEXTEST_TEST_THREADS: 10
# exclude distro since at this point we don't have compiled wasms which are required for compilation
run: cargo nextest run --release --all-features --no-fail-fast --workspace --exclude trust-graph-distro
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: "16"
registry-url: "https://registry.npmjs.org"
cache-dependency-path: "aqua/package-lock.json"
cache: "npm"
- run: npm i
working-directory: aqua
- run: npm run build
working-directory: aqua

2
.gitignore vendored
View File

@ -2,6 +2,8 @@ service/target
service/artifacts
builtin-package/*.wasm
trust-graph.tar.gz
distro/trust-graph-service
distro/target
**/*.rs.bk
**/.idea

3643
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,13 @@
[package]
name = "trust-graph"
version = "0.3.0"
authors = ["Fluence Labs"]
edition = "2018"
description = "trust graph"
license = "Apache-2.0"
repository = "https://github.com/fluencelabs/trust-graph"
[dependencies]
serde = { version = "1.0.118", features = ["derive"] }
fluence-keypair = { path = "./keypair", version = "0.8.1" }
serde_json = "1.0.58"
bs58 = "0.3.1"
failure = "0.1.6"
log = "0.4.11"
ref-cast = "1.0.2"
derivative = "2.1.1"
signature = "1.3.0"
serde_with = "1.6.0"
thiserror = "1.0.23"
sha2 = "0.9.5"
rand = "0.7.0"
nonempty = "0.7.0"
[workspace]
members = [
"trust-graph",
"keypair",
"service"
"service",
"distro"
]
[workspace.dependencies]
libp2p-core = { version = "0.36", default-features = false, features = [ "secp256k1", "rsa" ] }
libp2p-identity = { version = "0.2.1", default-features = false }
[patch.crates-io]
libp2p-identity = { git = "https://github.com/fluencelabs/rust-libp2p.git", branch = "rand-feature" }

140
admin/package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@fluencelabs/aqua": "^0.9.1-374",
"@fluencelabs/aqua": "^0.10.0",
"@fluencelabs/aqua-lib": "^0.6.0",
"@fluencelabs/fluence": "^0.27.5",
"@fluencelabs/fluence-network-environment": "^1.0.13",
@ -22,13 +22,13 @@
},
"../aqua": {
"name": "@fluencelabs/trust-graph",
"version": "0.2.2",
"version": "0.4.6",
"license": "MIT",
"dependencies": {
"@fluencelabs/aqua-lib": "^0.5.2"
"@fluencelabs/aqua-lib": "^0.7.0"
},
"devDependencies": {
"@fluencelabs/aqua": "^0.7.4-322"
"@fluencelabs/aqua": "^0.10.3"
}
},
"../aqua/node_modules/@fluencelabs/aqua": {
@ -687,13 +687,13 @@
}
},
"node_modules/@fluencelabs/aqua": {
"version": "0.9.1-374",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.9.1-374.tgz",
"integrity": "sha512-jF6oVE4h7bP/dQArKEfsy4UxbQbzACfVIBY/TFUL5D3np4ssjxrh15Y3gl1PwSWjlaPcDeFvAuStmcqfYQmLqQ==",
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.10.3.tgz",
"integrity": "sha512-v7Jy+KzZkUm7NuUgrp7UQ8gxuhykxuTU3JigCdxiZMcG3/zD+OtHzsSggVLxVjDP7CKuTcjEKZSCxObwHp/Tpw==",
"dependencies": {
"@fluencelabs/aqua-ipfs": "0.5.8",
"@fluencelabs/aqua-ipfs": "0.5.9",
"@fluencelabs/aqua-lib": "0.6.0",
"@fluencelabs/fluence": "0.27.5",
"@fluencelabs/fluence": "0.28.0",
"@fluencelabs/fluence-network-environment": "1.0.13",
"ipfs-http-client": "50.1.2"
},
@ -703,9 +703,9 @@
}
},
"node_modules/@fluencelabs/aqua-ipfs": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua-ipfs/-/aqua-ipfs-0.5.8.tgz",
"integrity": "sha512-jKlyGBm8oJAIQ3Ags58oJ8QVTlCYSvZQVTnX2SnugGXWVwt4+9qtqtvNT5MvWKK3M9lCFDbJJy/qVTjzPJlaiw==",
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua-ipfs/-/aqua-ipfs-0.5.9.tgz",
"integrity": "sha512-Vg7pYv4gEreOKfvzKEL5FchGqSKwat7JyKpqJO6h+FC5S1bl76UkI507+ExhijmUbQGznop8G33XFxyUi6q5SQ==",
"dependencies": {
"@fluencelabs/aqua-lib": "^0.5.2"
}
@ -720,6 +720,57 @@
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua-lib/-/aqua-lib-0.6.0.tgz",
"integrity": "sha512-ifjtCM93KO3LhzPkMxqmXhwLmrg/scjOiyTihEVg7ns5N+BVzaK1eWzdOdqGdl9ZVoah43pdlQUepEo7VdRmsw=="
},
"node_modules/@fluencelabs/aqua/node_modules/@fluencelabs/avm": {
"version": "0.35.3",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.35.3.tgz",
"integrity": "sha512-Y5mPPCmAUUKc5CDO12IL8mGEreWa7maVdX0MWCAH4+GvfLPFN1FxOMSKRYEtvkyVEL88pc9pd8cm5IRCBkFthg=="
},
"node_modules/@fluencelabs/aqua/node_modules/@fluencelabs/fluence": {
"version": "0.28.0",
"resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.28.0.tgz",
"integrity": "sha512-SXb2vjTj8m/nw4jEILV0tu9VIFprGo8mNb2nOB5btxdsOI8GzQZkpGzTLrSd/+UagIo2GdxAu0GhBP8dxZXaqg==",
"deprecated": "fluencelabs/fluence is deprecated in favor of a thinner CDN-distributed .js bundle, please see the following link for installation instructions https://github.com/fluencelabs/js-client#installation",
"dependencies": {
"@fluencelabs/avm": "0.35.3",
"@fluencelabs/connection": "0.2.0",
"@fluencelabs/interfaces": "0.1.0",
"@fluencelabs/keypair": "0.2.0",
"@fluencelabs/marine-js": "0.3.37",
"async": "3.2.4",
"base64-js": "^1.5.1",
"browser-or-node": "2.0.0",
"bs58": "5.0.0",
"buffer": "^6.0.3",
"cids": "1.1.9",
"loglevel": "1.8.1",
"multiformats": "9.9.0",
"peer-id": "0.16.0",
"platform": "^1.3.6",
"rxjs": "^7.5.5",
"ts-pattern": "3.3.3",
"uuid": "8.3.2"
},
"bin": {
"copy-marine": "dist/tools/copyMarine.js"
},
"engines": {
"node": ">=10",
"pnpm": ">=3"
}
},
"node_modules/@fluencelabs/aqua/node_modules/base-x": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz",
"integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw=="
},
"node_modules/@fluencelabs/aqua/node_modules/bs58": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
"integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
"dependencies": {
"base-x": "^4.0.0"
}
},
"node_modules/@fluencelabs/avm": {
"version": "0.31.10",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.31.10.tgz",
@ -7936,21 +7987,66 @@
}
},
"@fluencelabs/aqua": {
"version": "0.9.1-374",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.9.1-374.tgz",
"integrity": "sha512-jF6oVE4h7bP/dQArKEfsy4UxbQbzACfVIBY/TFUL5D3np4ssjxrh15Y3gl1PwSWjlaPcDeFvAuStmcqfYQmLqQ==",
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua/-/aqua-0.10.3.tgz",
"integrity": "sha512-v7Jy+KzZkUm7NuUgrp7UQ8gxuhykxuTU3JigCdxiZMcG3/zD+OtHzsSggVLxVjDP7CKuTcjEKZSCxObwHp/Tpw==",
"requires": {
"@fluencelabs/aqua-ipfs": "0.5.8",
"@fluencelabs/aqua-ipfs": "0.5.9",
"@fluencelabs/aqua-lib": "0.6.0",
"@fluencelabs/fluence": "0.27.5",
"@fluencelabs/fluence": "0.28.0",
"@fluencelabs/fluence-network-environment": "1.0.13",
"ipfs-http-client": "50.1.2"
},
"dependencies": {
"@fluencelabs/avm": {
"version": "0.35.3",
"resolved": "https://registry.npmjs.org/@fluencelabs/avm/-/avm-0.35.3.tgz",
"integrity": "sha512-Y5mPPCmAUUKc5CDO12IL8mGEreWa7maVdX0MWCAH4+GvfLPFN1FxOMSKRYEtvkyVEL88pc9pd8cm5IRCBkFthg=="
},
"@fluencelabs/fluence": {
"version": "0.28.0",
"resolved": "https://registry.npmjs.org/@fluencelabs/fluence/-/fluence-0.28.0.tgz",
"integrity": "sha512-SXb2vjTj8m/nw4jEILV0tu9VIFprGo8mNb2nOB5btxdsOI8GzQZkpGzTLrSd/+UagIo2GdxAu0GhBP8dxZXaqg==",
"requires": {
"@fluencelabs/avm": "0.35.3",
"@fluencelabs/connection": "0.2.0",
"@fluencelabs/interfaces": "0.1.0",
"@fluencelabs/keypair": "0.2.0",
"@fluencelabs/marine-js": "0.3.37",
"async": "3.2.4",
"base64-js": "^1.5.1",
"browser-or-node": "2.0.0",
"bs58": "5.0.0",
"buffer": "^6.0.3",
"cids": "1.1.9",
"loglevel": "1.8.1",
"multiformats": "9.9.0",
"peer-id": "0.16.0",
"platform": "^1.3.6",
"rxjs": "^7.5.5",
"ts-pattern": "3.3.3",
"uuid": "8.3.2"
}
},
"base-x": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz",
"integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw=="
},
"bs58": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
"integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
"requires": {
"base-x": "^4.0.0"
}
}
}
},
"@fluencelabs/aqua-ipfs": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua-ipfs/-/aqua-ipfs-0.5.8.tgz",
"integrity": "sha512-jKlyGBm8oJAIQ3Ags58oJ8QVTlCYSvZQVTnX2SnugGXWVwt4+9qtqtvNT5MvWKK3M9lCFDbJJy/qVTjzPJlaiw==",
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/@fluencelabs/aqua-ipfs/-/aqua-ipfs-0.5.9.tgz",
"integrity": "sha512-Vg7pYv4gEreOKfvzKEL5FchGqSKwat7JyKpqJO6h+FC5S1bl76UkI507+ExhijmUbQGznop8G33XFxyUi6q5SQ==",
"requires": {
"@fluencelabs/aqua-lib": "^0.5.2"
},
@ -8100,8 +8196,8 @@
"@fluencelabs/trust-graph": {
"version": "file:../aqua",
"requires": {
"@fluencelabs/aqua": "^0.7.4-322",
"@fluencelabs/aqua-lib": "^0.5.2"
"@fluencelabs/aqua": "^0.10.3",
"@fluencelabs/aqua-lib": "^0.7.0"
},
"dependencies": {
"@fluencelabs/aqua": {

View File

@ -13,7 +13,7 @@
"author": "Fluence Labs",
"license": "MIT",
"dependencies": {
"@fluencelabs/aqua": "^0.9.1-374",
"@fluencelabs/aqua": "^0.10.0",
"@fluencelabs/aqua-lib": "^0.6.0",
"@fluencelabs/fluence": "^0.27.5",
"@fluencelabs/fluence-network-environment": "^1.0.13",

51
aqua/CHANGELOG.md Normal file
View File

@ -0,0 +1,51 @@
# Changelog
## [0.4.7](https://github.com/fluencelabs/trust-graph/compare/trust-graph-api-v0.4.6...trust-graph-api-v0.4.7) (2023-07-04)
### Miscellaneous Chores
* **trust-graph-api:** Synchronize trust-graph, wasm and api versions
## [0.4.6](https://github.com/fluencelabs/trust-graph/compare/trust-graph-api-v0.4.5...trust-graph-api-v0.4.6) (2023-06-30)
### Reverts
* release master ([#110](https://github.com/fluencelabs/trust-graph/issues/110)) ([d80a43b](https://github.com/fluencelabs/trust-graph/commit/d80a43bcff721aff8fadf3d2d5c252804ce27a6c))
## [0.4.5](https://github.com/fluencelabs/trust-graph/compare/trust-graph-api-v0.4.4...trust-graph-api-v0.4.5) (2023-05-09)
### Miscellaneous Chores
* **trust-graph-api:** Synchronize trust-graph, wasm and api versions
## [0.4.4](https://github.com/fluencelabs/trust-graph/compare/trust-graph-api-v0.4.3...trust-graph-api-v0.4.4) (2023-05-09)
### Miscellaneous Chores
* **trust-graph-api:** Synchronize trust-graph, wasm and api versions
## [0.4.3](https://github.com/fluencelabs/trust-graph/compare/trust-graph-api-v0.4.1...trust-graph-api-v0.4.3) (2023-05-08)
### Miscellaneous Chores
* **trust-graph-api:** Synchronize trust-graph, wasm and api versions
## [0.4.1](https://github.com/fluencelabs/trust-graph/compare/trust-graph-api-v0.4.0...trust-graph-api-v0.4.1) (2023-04-13)
### Bug Fixes
* **deps:** update aqua to 0.10.3 ([fe902ac](https://github.com/fluencelabs/trust-graph/commit/fe902acc50a6b4c6bf97c487f3e47ae0f5ef8a95))
* **deps:** update aqua-lib to 0.7.0 ([fe902ac](https://github.com/fluencelabs/trust-graph/commit/fe902acc50a6b4c6bf97c487f3e47ae0f5ef8a95))
## [0.4.0](https://github.com/fluencelabs/trust-graph/compare/trust-graph-api-v0.3.2...trust-graph-api-v0.4.0) (2023-03-15)
### Miscellaneous Chores
* **trust-graph-api:** Synchronize trust-graph, wasm and api versions

4780
aqua/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
{
"name": "@fluencelabs/trust-graph",
"version": "0.2.2",
"version": "0.4.7",
"description": "Aqua Trust Graph API library",
"files": [
"*.aqua"
],
"dependencies": {
"@fluencelabs/aqua-lib": "^0.5.2"
"@fluencelabs/aqua-lib": "^0.7.0"
},
"scripts": {
"generate-aqua": "../service/build.sh",
@ -31,6 +31,6 @@
},
"homepage": "https://github.com/fluencelabs/trust-graph#readme",
"devDependencies": {
"@fluencelabs/aqua": "^0.7.4-322"
"@fluencelabs/aqua": "^0.10.3"
}
}

15
build.sh Executable file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -o errexit -o nounset -o pipefail
# set current working directory to script directory to run script from everywhere
cd "$(dirname "$0")"
./service/build.sh
TARGET="distro/trust-graph-service/"
mkdir -p "$TARGET"
cp -v ./distro/init_certs.json service/artifacts/trust-graph.wasm service/artifacts/sqlite3.wasm distro/Config.toml "$TARGET"
cd distro
cargo build

View File

@ -1,7 +0,0 @@
{
"name": "trust-graph",
"dependencies": [
"name:sqlite3",
"name:trust-graph"
]
}

View File

@ -3,20 +3,39 @@ set -o pipefail -o nounset -o errexit
# set current working directory to script directory to run script from everywhere
cd "$(dirname "$0")"
SCRIPT_DIR="$(pwd)"
PACKAGE_DIR="$(pwd)/../package/trust-graph"
(
rm -rf $PACKAGE_DIR/*
mkdir -p $PACKAGE_DIR
)
(
echo "*** copy wasm files ***"
cd ../service
cp artifacts/*.wasm "$SCRIPT_DIR"
cp artifacts/*.wasm "$PACKAGE_DIR"
)
(
echo "*** copy on_start script ***"
cp on_start.json "$PACKAGE_DIR"
cp on_start.air "$PACKAGE_DIR"
)
TRUST_GRAPH_CID=$(ipfs add -q --only-hash --cid-version=1 --chunker=size-262144 $PACKAGE_DIR/trust-graph.wasm)
SQLITE_CID=$(ipfs add -q --only-hash --cid-version=1 --chunker=size-262144 $PACKAGE_DIR/sqlite3.wasm)
mv $PACKAGE_DIR/trust-graph.wasm "$PACKAGE_DIR"/"$TRUST_GRAPH_CID".wasm
mv $PACKAGE_DIR/sqlite3.wasm "$PACKAGE_DIR"/"$SQLITE_CID".wasm
cp trust-graph_config.json "$PACKAGE_DIR"/"$TRUST_GRAPH_CID"_config.json
cp sqlite3_config.json "$PACKAGE_DIR"/"$SQLITE_CID"_config.json
# write blueprint.json
echo "{}" | jq --arg trust_graph_cid "$TRUST_GRAPH_CID" --arg sqlite_cid "$SQLITE_CID" '{"name": "trust-graph", "dependencies":[{"/":$sqlite_cid},{"/":$trust_graph_cid}]}' > "$PACKAGE_DIR/blueprint.json"
(
echo "*** create builtin distribution package ***"
cd ..
mv builtin-package trust-graph
tar --exclude="package.sh" -f trust-graph.tar.gz -zcv ./trust-graph
mv trust-graph builtin-package
cd $PACKAGE_DIR/..
tar -f ../trust-graph.tar.gz -zcv ./trust-graph
)
echo "*** done ***"

20
distro/CHANGELOG.md Normal file
View File

@ -0,0 +1,20 @@
# Changelog
## [0.4.7](https://github.com/fluencelabs/trust-graph/compare/distro-v0.4.6...distro-v0.4.7) (2023-07-04)
### Miscellaneous Chores
* **distro:** Synchronize trust-graph, wasm and api versions
## [0.4.6](https://github.com/fluencelabs/trust-graph/compare/distro-v0.4.5...distro-v0.4.6) (2023-06-30)
### Features
* add distro crate [fixes NET-463] ([#93](https://github.com/fluencelabs/trust-graph/issues/93)) ([3ba3855](https://github.com/fluencelabs/trust-graph/commit/3ba3855892ae355962212a0a42099dd9f9820800))
### Reverts
* release master ([#110](https://github.com/fluencelabs/trust-graph/issues/110)) ([d80a43b](https://github.com/fluencelabs/trust-graph/commit/d80a43bcff721aff8fadf3d2d5c252804ce27a6c))

18
distro/Cargo.toml Normal file
View File

@ -0,0 +1,18 @@
[package]
name = "trust-graph-distro"
version = "0.4.7"
edition = "2021"
build = "build.rs"
license = "Apache-2.0"
include = [ "/src", "build.rs", "Cargo.toml", "trust-graph-service"]
description = "Distribution package for the trust-graph service"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
maplit = "1.0.2"
serde = "1.0.160"
serde_json = "1.0.96"
lazy_static = "1.4.0"
[build-dependencies]
built = "0.6.0"

14
distro/Config.toml Normal file
View File

@ -0,0 +1,14 @@
modules_dir = "."
[[module]]
name = "sqlite3"
logger_enabled = true
[module.wasi]
mapped_dirs = { "tmp" = "data" }
[[module]]
name = "trust-graph"
logger_enabled = true
[module.wasi]
mapped_dirs = { "tmp" = "data" }

3
distro/build.rs Normal file
View File

@ -0,0 +1,3 @@
fn main() {
built::write_built_file().expect("Failed to acquire build-time information")
}

1
distro/init_certs.json Normal file

File diff suppressed because one or more lines are too long

60
distro/src/lib.rs Normal file
View File

@ -0,0 +1,60 @@
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
#[cfg(not(feature = "cargo-clippy"))]
pub const TRUST_GRAPH_WASM: &[u8] = include_bytes!("../trust-graph-service/trust-graph.wasm");
#[cfg(feature = "cargo-clippy")]
pub const TRUST_GRAPH_WASM: &[u8] = &[];
#[cfg(not(feature = "cargo-clippy"))]
pub const SQLITE_WASM: &[u8] = include_bytes!("../trust-graph-service/sqlite3.wasm");
#[cfg(feature = "cargo-clippy")]
pub const SQLITE_WASM: &[u8] = &[];
#[cfg(not(feature = "cargo-clippy"))]
pub const CONFIG: &[u8] = include_bytes!("../trust-graph-service/Config.toml");
#[cfg(feature = "cargo-clippy")]
pub const CONFIG: &[u8] = &[];
#[cfg(not(feature = "cargo-clippy"))]
pub const KRAS_CERTS_JSON: &str = include_str!("../trust-graph-service/init_certs.json");
#[cfg(feature = "cargo-clippy")]
pub const KRAS_CERTS_JSON: &str = "{}";
pub mod build_info {
include!(concat!(env!("OUT_DIR"), "/built.rs"));
}
pub use build_info::PKG_VERSION as VERSION;
pub fn modules() -> std::collections::HashMap<&'static str, &'static [u8]> {
maplit::hashmap! {
"sqlite3" => SQLITE_WASM,
"trust-graph" => TRUST_GRAPH_WASM,
}
}
#[derive(Deserialize, Serialize)]
pub struct Certs {
pub root_node: String,
pub max_chain_length: u32,
pub certs: Vec<Cert>,
}
#[derive(Deserialize, Serialize)]
pub struct Cert {
pub chain: Vec<Trust>,
}
#[derive(Deserialize, Serialize)]
pub struct Trust {
pub issued_for: String,
pub expires_at: u64,
pub signature: String,
pub sig_type: String,
pub issued_at: u64,
}
lazy_static! {
pub static ref KRAS_CERTS: Certs = serde_json::from_str(KRAS_CERTS_JSON).unwrap();
}

1518
example/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -4,6 +4,49 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.10.3](https://github.com/fluencelabs/trust-graph/compare/keypair-v0.10.2...keypair-v0.10.3) (2023-07-04)
### Bug Fixes
* **keypair:** deserialize libp2p keypair from secret key ([#116](https://github.com/fluencelabs/trust-graph/issues/116)) ([ee330a7](https://github.com/fluencelabs/trust-graph/commit/ee330a715a902e48fc9b61d662ffcd950a26379c))
## [0.10.2](https://github.com/fluencelabs/trust-graph/compare/keypair-v0.10.1...keypair-v0.10.2) (2023-06-30)
### Features
* update libp2p identity ([#109](https://github.com/fluencelabs/trust-graph/issues/109)) ([d04120b](https://github.com/fluencelabs/trust-graph/commit/d04120bacf802a7e1127f4955b7391b0a4353128))
### Bug Fixes
* **keypair:** update description ([#105](https://github.com/fluencelabs/trust-graph/issues/105)) ([f7ef0f8](https://github.com/fluencelabs/trust-graph/commit/f7ef0f8da095fe1fef80faaa0b0c2d5ef854bd16))
### Reverts
* release master ([#110](https://github.com/fluencelabs/trust-graph/issues/110)) ([d80a43b](https://github.com/fluencelabs/trust-graph/commit/d80a43bcff721aff8fadf3d2d5c252804ce27a6c))
## [0.10.1](https://github.com/fluencelabs/trust-graph/compare/keypair-v0.10.0...keypair-v0.10.1) (2023-05-02)
### Features
* **keypair:** Make `KeyFormat` more convenient ([#91](https://github.com/fluencelabs/trust-graph/issues/91)) ([9b942ea](https://github.com/fluencelabs/trust-graph/commit/9b942eacca49d0468b4d7512667102363a6c9aa3))
## [0.10.0](https://github.com/fluencelabs/trust-graph/compare/keypair-v0.9.0...keypair-v0.10.0) (2023-03-15)
### ⚠ BREAKING CHANGES
* **deps:** update libp2p to 0.39.1 and other deps ([#77](https://github.com/fluencelabs/trust-graph/issues/77))
### Features
* **deps:** update libp2p to 0.39.1 and other deps ([#77](https://github.com/fluencelabs/trust-graph/issues/77)) ([080503d](https://github.com/fluencelabs/trust-graph/commit/080503dcfa2ecf8d09167ff9fe7f750fadf49035))
* **keypair:** add KeyPair::from_secret_key ([#50](https://github.com/fluencelabs/trust-graph/issues/50)) ([a6ce8d9](https://github.com/fluencelabs/trust-graph/commit/a6ce8d9eee20e1ea24eb27c38ac6df6d878292ae))
## [Unreleased]
## [0.8.1] - 2022-10-06

View File

@ -1,33 +1,26 @@
[package]
name = "fluence-keypair"
version = "0.8.1"
version = "0.10.3"
authors = ["Fluence Labs"]
edition = "2018"
description = "identity"
edition = "2021"
description = "unified keypair API based on libp2p-identity"
license = "Apache-2.0"
repository = "https://github.com/fluencelabs/trust-graph"
[dependencies]
serde = { version = "1.0.118", features = ["derive"] }
serde_json = "1.0.58"
bs58 = "0.3.1"
ed25519-dalek = { version = "1.0.1", features = ["serde", "std"] }
rand = "0.7.0"
signature = "1.3.0"
ed25519 = "1.0.3"
serde_with = "1.6.0"
bs58 = "0.5.0"
ed25519-dalek = { version = "1.0.1", features = ["serde", "u64_backend"], default-features = false }
thiserror = "1.0.23"
lazy_static = "1.2"
libsecp256k1 = "0.7.1"
asn1_der = "0.6.1"
sha2 = "0.9.1"
lazy_static = "1.4"
sha2 = "0.10.6"
zeroize = "1"
serde_bytes = "0.11"
libp2p-core = { workspace = true }
eyre = "0.6.5"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ring = { version = "0.16.9", features = ["alloc", "std"], default-features = false }
libp2p-identity = { workspace = true, default-features = false, features = ["peerid", "ed25519"] }
multihash = { version = "0.18.0", features = ["identity"] }
# rand fails to compile for restricted environments like NEAR contracts
rand = { version = "0.8.5", optional = true }
[dev-dependencies]
quickcheck = "0.9.0"
quickcheck = "1.0.3"

View File

@ -1,3 +0,0 @@
[toolchain]
channel = "nightly-2022-08-30"
targets = [ "x86_64-apple-darwin", "x86_64-unknown-linux-gnu" ]

View File

@ -22,6 +22,7 @@
use crate::error::{DecodingError, SigningError, VerificationError};
use core::fmt;
use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _};
#[cfg(feature = "rand")]
use rand::RngCore;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
@ -32,6 +33,7 @@ pub struct Keypair(ed25519::Keypair);
impl Keypair {
/// Generate a new Ed25519 keypair.
#[cfg(feature = "rand")]
pub fn generate() -> Self {
Keypair::from(SecretKey::generate())
}
@ -51,12 +53,17 @@ impl Keypair {
kp.zeroize();
Keypair(k)
})
.map_err(DecodingError::Ed25519)
.map_err(|_| DecodingError::Ed25519())
}
/// Sign a message using the private key of this keypair.
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
Ok(self.0.try_sign(msg)?.to_bytes().to_vec())
Ok(self
.0
.try_sign(msg)
.map_err(|_| SigningError::Ed25519())?
.to_bytes()
.to_vec())
}
/// Get the public key of this keypair.
@ -126,9 +133,8 @@ impl PublicKey {
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
ed25519::Signature::try_from(sig)
.and_then(|s| self.0.verify(msg, &s))
.map_err(|e| {
.map_err(|_| {
VerificationError::Ed25519(
e,
bs58::encode(sig).into_string(),
bs58::encode(self.0.as_bytes()).into_string(),
)
@ -144,7 +150,7 @@ impl PublicKey {
/// Decode a public key from a byte array as produced by `encode`.
pub fn decode(bytes: &[u8]) -> Result<Self, DecodingError> {
ed25519::PublicKey::from_bytes(bytes)
.map_err(DecodingError::Ed25519)
.map_err(|_| DecodingError::Ed25519())
.map(PublicKey)
}
}
@ -174,6 +180,7 @@ impl fmt::Debug for SecretKey {
impl SecretKey {
/// Generate a new Ed25519 secret key.
#[cfg(feature = "rand")]
pub fn generate() -> Self {
let mut bytes = [0u8; 32];
rand::thread_rng().fill_bytes(&mut bytes);
@ -189,7 +196,8 @@ impl SecretKey {
/// returned.
pub fn from_bytes(mut sk_bytes: impl AsMut<[u8]>) -> Result<Self, DecodingError> {
let sk_bytes = sk_bytes.as_mut();
let secret = ed25519::SecretKey::from_bytes(&*sk_bytes).map_err(DecodingError::Ed25519)?;
let secret =
ed25519::SecretKey::from_bytes(&*sk_bytes).map_err(|_| DecodingError::Ed25519())?;
sk_bytes.zeroize();
Ok(SecretKey(secret))
}
@ -198,9 +206,10 @@ impl SecretKey {
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct Signature(pub Vec<u8>);
#[cfg(test)]
#[cfg(all(test, feature = "rand"))]
mod tests {
use super::*;
use crate::KeyPair;
use quickcheck::*;
fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool {
@ -218,6 +227,17 @@ mod tests {
QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
}
#[test]
fn ed25519_keypair_convert() {
fn prop() -> bool {
let kp1 = KeyPair::generate_ed25519();
let libp2p_kp: libp2p_identity::Keypair = kp1.clone().into();
let kp2: KeyPair = libp2p_kp.into();
kp1.public() == kp2.public() && kp1.secret().unwrap() == kp2.secret().unwrap()
}
QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
}
#[test]
fn ed25519_keypair_from_secret() {
fn prop() -> bool {

View File

@ -31,18 +31,8 @@ pub enum Error {
/// An error during decoding of key material.
#[derive(ThisError, Debug)]
pub enum DecodingError {
#[error("Failed to decode with ed25519: {0}")]
Ed25519(
#[from]
#[source]
ed25519_dalek::ed25519::Error,
),
#[error("Failed to decode with RSA")]
Rsa,
#[error("Failed to decode with secp256k1")]
Secp256k1,
#[error("RSA keypair decoding is not supported yet")]
KeypairDecodingIsNotSupported,
#[error("Failed to decode with ed25519")]
Ed25519(),
#[error("Invalid type prefix")]
InvalidTypeByte,
#[error("Cannot decode public key from base58 :{0}")]
@ -56,32 +46,13 @@ pub enum DecodingError {
/// An error during signing of a message.
#[derive(ThisError, Debug)]
pub enum SigningError {
#[error("Failed to sign with ed25519: {0}")]
Ed25519(
#[from]
#[source]
ed25519_dalek::ed25519::Error,
),
#[error("Failed to sign with RSA")]
Rsa,
#[error("Failed to sign with secp256k1: {0}")]
Secp256k1(
#[from]
#[source]
libsecp256k1::Error,
),
#[error("Failed to sign with ed25519")]
Ed25519(),
}
/// An error during verification of a message.
#[derive(ThisError, Debug)]
pub enum VerificationError {
#[error("Failed to verify signature {1} with {2} ed25519 public key: {0}")]
Ed25519(#[source] ed25519_dalek::ed25519::Error, String, String),
#[cfg(not(target_arch = "wasm32"))]
#[error("Failed to verify signature {1} with {2} RSA public key: {0}")]
Rsa(#[source] ring::error::Unspecified, String, String),
#[error("Failed to verify signature {1} with {2} secp256k1 public key: {0}")]
Secp256k1(#[source] libsecp256k1::Error, String, String),
#[error("Failed to verify signature {0} with {1} ed25519 public key")]
Ed25519(String, String),
}

View File

@ -22,11 +22,8 @@
use crate::ed25519;
use crate::error::{DecodingError, Error, SigningError, VerificationError};
use crate::public_key::PublicKey;
#[cfg(not(target_arch = "wasm32"))]
use crate::rsa;
use crate::secp256k1;
use crate::signature::Signature;
use libp2p_core::PeerId;
use libp2p_identity::{KeyType, Keypair, PeerId};
use std::convert::TryFrom;
use std::str::FromStr;
@ -47,12 +44,9 @@ use std::str::FromStr;
/// let keypair = Keypair::rsa_from_pkcs8(&mut bytes);
/// ```
///
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyFormat {
Ed25519,
#[cfg(not(target_arch = "wasm32"))]
Rsa,
Secp256k1,
}
impl FromStr for KeyFormat {
@ -62,9 +56,6 @@ impl FromStr for KeyFormat {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ed25519" => Ok(KeyFormat::Ed25519),
"secp256k1" => Ok(KeyFormat::Secp256k1),
#[cfg(not(target_arch = "wasm32"))]
"rsa" => Ok(KeyFormat::Rsa),
_ => Err(Error::InvalidKeyFormat(s.to_string())),
}
}
@ -76,9 +67,6 @@ impl TryFrom<u8> for KeyFormat {
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(KeyFormat::Ed25519),
#[cfg(not(target_arch = "wasm32"))]
1 => Ok(KeyFormat::Rsa),
2 => Ok(KeyFormat::Secp256k1),
_ => Err(DecodingError::InvalidTypeByte),
}
}
@ -88,9 +76,6 @@ impl From<KeyFormat> for u8 {
fn from(kf: KeyFormat) -> Self {
match kf {
KeyFormat::Ed25519 => 0,
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => 1,
KeyFormat::Secp256k1 => 2,
}
}
}
@ -99,72 +84,45 @@ impl From<KeyFormat> for String {
fn from(kf: KeyFormat) -> Self {
match kf {
KeyFormat::Ed25519 => "ed25519".to_string(),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => "rsa".to_string(),
KeyFormat::Secp256k1 => "secp256k1".to_string(),
}
}
}
#[derive(Clone)]
pub enum KeyPair {
/// An Ed25519 keypair.
Ed25519(ed25519::Keypair),
#[cfg(not(target_arch = "wasm32"))]
/// An RSA keypair.
Rsa(rsa::Keypair),
/// A Secp256k1 keypair.
Secp256k1(secp256k1::Keypair),
}
impl KeyPair {
#[cfg(feature = "rand")]
pub fn generate(format: KeyFormat) -> KeyPair {
match format {
KeyFormat::Ed25519 => KeyPair::generate_ed25519(),
KeyFormat::Secp256k1 => KeyPair::generate_secp256k1(),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => todo!("rsa generation is not supported yet!"),
}
}
/// Generate a new Ed25519 keypair.
#[cfg(feature = "rand")]
pub fn generate_ed25519() -> KeyPair {
KeyPair::Ed25519(ed25519::Keypair::generate())
}
/// Generate a new Secp256k1 keypair.
pub fn generate_secp256k1() -> KeyPair {
KeyPair::Secp256k1(secp256k1::Keypair::generate())
}
/// Decode an keypair from a DER-encoded secret key in PKCS#8 PrivateKeyInfo
/// format (i.e. unencrypted) as defined in [RFC5208].
///
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
#[cfg(not(target_arch = "wasm32"))]
pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<KeyPair, DecodingError> {
rsa::Keypair::from_pkcs8(pkcs8_der).map(KeyPair::Rsa)
}
/// Decode a keypair from a DER-encoded Secp256k1 secret key in an ECPrivateKey
/// structure as defined in [RFC5915].
///
/// [RFC5915]: https://tools.ietf.org/html/rfc5915
pub fn secp256k1_from_der(der: &mut [u8]) -> Result<KeyPair, DecodingError> {
secp256k1::SecretKey::from_der(der)
.map(|sk| KeyPair::Secp256k1(secp256k1::Keypair::from(sk)))
}
/// Sign a message using the private key of this keypair, producing
/// a signature that can be verified using the corresponding public key.
pub fn sign(&self, msg: &[u8]) -> Result<Signature, SigningError> {
use KeyPair::*;
match self {
Ed25519(ref pair) => Ok(Signature::Ed25519(ed25519::Signature(pair.sign(msg)?))),
#[cfg(not(target_arch = "wasm32"))]
Rsa(ref pair) => Ok(Signature::Rsa(rsa::Signature(pair.sign(msg)?))),
Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature(
pair.secret().sign(msg)?,
))),
}
}
/// Get the key format of this keypair.
pub fn key_format(&self) -> KeyFormat {
use KeyPair::*;
match self {
Ed25519(_) => KeyFormat::Ed25519,
}
}
@ -173,9 +131,6 @@ impl KeyPair {
use KeyPair::*;
match self {
Ed25519(pair) => PublicKey::Ed25519(pair.public()),
#[cfg(not(target_arch = "wasm32"))]
Rsa(pair) => PublicKey::Rsa(pair.public()),
Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
}
}
@ -183,9 +138,6 @@ impl KeyPair {
use KeyPair::*;
match self {
Ed25519(pair) => Ok(pair.secret().0.to_bytes().to_vec()),
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => Err(eyre::eyre!("secret key is not available for RSA")),
Secp256k1(pair) => Ok(pair.secret().to_bytes().to_vec()),
}
}
@ -202,9 +154,6 @@ impl KeyPair {
use KeyPair::*;
match self {
Ed25519(kp) => kp.encode().to_vec(),
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => todo!("rsa encoding is not supported yet!"),
Secp256k1(kp) => kp.secret().to_bytes().to_vec(),
}
}
@ -213,9 +162,6 @@ impl KeyPair {
match format {
KeyFormat::Ed25519 => Ok(Ed25519(ed25519::Keypair::decode(&mut bytes)?)),
KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported),
}
}
@ -224,9 +170,6 @@ impl KeyPair {
match format {
KeyFormat::Ed25519 => Ok(Ed25519(ed25519::SecretKey::from_bytes(bytes)?.into())),
KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported),
}
}
@ -235,42 +178,35 @@ impl KeyPair {
}
}
impl From<libp2p_core::identity::Keypair> for KeyPair {
fn from(key: libp2p_core::identity::Keypair) -> Self {
use libp2p_core::identity::Keypair::*;
match key {
Ed25519(kp) => KeyPair::Ed25519(ed25519::Keypair::decode(&mut kp.encode()).unwrap()),
#[cfg(not(target_arch = "wasm32"))]
// safety: these Keypair structures are identical
Rsa(kp) => KeyPair::Rsa(unsafe {
std::mem::transmute::<libp2p_core::identity::rsa::Keypair, rsa::Keypair>(kp)
}),
Secp256k1(kp) => KeyPair::Secp256k1(secp256k1::Keypair::from(
secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(),
)),
impl From<libp2p_identity::Keypair> for KeyPair {
fn from(key: libp2p_identity::Keypair) -> Self {
fn convert_keypair(key: Keypair) -> eyre::Result<KeyPair> {
match key.key_type() {
KeyType::Ed25519 => {
let kp = key.try_into_ed25519()?;
let raw_kp = ed25519::Keypair::decode(&mut kp.to_bytes())?;
Ok(KeyPair::Ed25519(raw_kp))
}
_ => unimplemented!("key type not supported: {:?}", key.key_type()),
}
}
convert_keypair(key).expect("Could not convert keypair")
}
}
impl From<KeyPair> for libp2p_core::identity::Keypair {
impl From<KeyPair> for libp2p_identity::Keypair {
fn from(key: KeyPair) -> Self {
use libp2p_core::identity;
use libp2p_core::identity::Keypair;
use KeyPair::*;
match key {
Ed25519(kp) => Keypair::Ed25519(
identity::ed25519::Keypair::decode(kp.encode().to_vec().as_mut_slice()).unwrap(),
),
#[cfg(not(target_arch = "wasm32"))]
// safety: these Keypair structures are identical
Rsa(kp) => Keypair::Rsa(unsafe {
std::mem::transmute::<rsa::Keypair, libp2p_core::identity::rsa::Keypair>(kp)
}),
Secp256k1(kp) => Keypair::Secp256k1(identity::secp256k1::Keypair::from(
identity::secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(),
)),
fn convert_keypair(key: KeyPair) -> eyre::Result<libp2p_identity::Keypair> {
match key {
KeyPair::Ed25519(kp) => {
// for some reason, libp2p takes SecretKey's 32 bytes here instead of Keypair's 64 bytes
let secret_bytes = kp.secret().0.to_bytes();
let kp = libp2p_identity::Keypair::ed25519_from_bytes(secret_bytes)?;
Ok(kp)
}
}
}
convert_keypair(key).expect("Could not convert key pair")
}
}

View File

@ -30,9 +30,6 @@ mod ed25519;
pub mod error;
pub mod key_pair;
pub mod public_key;
#[cfg(not(target_arch = "wasm32"))]
mod rsa;
mod secp256k1;
pub mod signature;
pub use crate::public_key::PublicKey;
@ -41,7 +38,7 @@ pub use key_pair::KeyFormat;
pub use key_pair::KeyPair;
pub mod peerid_serializer {
use libp2p_core::PeerId;
use libp2p_identity::PeerId;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::str::FromStr;
@ -58,7 +55,7 @@ pub mod peerid_serializer {
{
let str = String::deserialize(deserializer)?;
PeerId::from_str(&str).map_err(|e| {
serde::de::Error::custom(format!("peer id deserialization failed for {:?}", e))
serde::de::Error::custom(format!("peer id deserialization failed for {e:?}"))
})
}
}

View File

@ -15,13 +15,10 @@
*/
use crate::ed25519;
use crate::error::{DecodingError, VerificationError};
#[cfg(not(target_arch = "wasm32"))]
use crate::rsa;
use crate::secp256k1;
use crate::signature::Signature;
use crate::key_pair::KeyFormat;
use libp2p_core::PeerId;
use libp2p_identity::{KeyType, PeerId};
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
@ -30,11 +27,6 @@ use std::convert::TryFrom;
pub enum PublicKey {
/// A public Ed25519 key.
Ed25519(ed25519::PublicKey),
#[cfg(not(target_arch = "wasm32"))]
/// A public RSA key.
Rsa(rsa::PublicKey),
/// A public Secp256k1 key.
Secp256k1(secp256k1::PublicKey),
}
impl PublicKey {
@ -47,9 +39,6 @@ impl PublicKey {
use PublicKey::*;
match self {
Ed25519(pk) => pk.verify(msg, sig.to_vec()),
#[cfg(not(target_arch = "wasm32"))]
Rsa(pk) => pk.verify(msg, sig.to_vec()),
Secp256k1(pk) => pk.verify(msg, sig.to_vec()),
}
}
@ -59,9 +48,6 @@ impl PublicKey {
match self {
Ed25519(pk) => result.extend(pk.encode().to_vec()),
#[cfg(not(target_arch = "wasm32"))]
Rsa(pk) => result.extend(pk.to_pkcs1()),
Secp256k1(pk) => result.extend(pk.encode().to_vec()),
};
result
@ -70,13 +56,6 @@ impl PublicKey {
pub fn decode(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
match KeyFormat::try_from(bytes[0])? {
KeyFormat::Ed25519 => Ok(PublicKey::Ed25519(ed25519::PublicKey::decode(&bytes[1..])?)),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => Ok(PublicKey::Rsa(rsa::PublicKey::from_pkcs1(
bytes[1..].to_owned(),
)?)),
KeyFormat::Secp256k1 => Ok(PublicKey::Secp256k1(secp256k1::PublicKey::decode(
&bytes[1..],
)?)),
}
}
@ -84,9 +63,6 @@ impl PublicKey {
use PublicKey::*;
match self {
Ed25519(_) => KeyFormat::Ed25519.into(),
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => KeyFormat::Rsa.into(),
Secp256k1(_) => KeyFormat::Secp256k1.into(),
}
}
@ -102,9 +78,6 @@ impl PublicKey {
match self {
Ed25519(pk) => pk.encode().to_vec(),
#[cfg(not(target_arch = "wasm32"))]
Rsa(pk) => pk.to_pkcs1().to_vec(),
Secp256k1(pk) => pk.encode().to_vec(),
}
}
@ -117,53 +90,47 @@ impl PublicKey {
match self {
Ed25519(_) => KeyFormat::Ed25519,
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => KeyFormat::Rsa,
Secp256k1(_) => KeyFormat::Secp256k1,
}
}
}
impl From<libp2p_core::identity::PublicKey> for PublicKey {
fn from(key: libp2p_core::identity::PublicKey) -> Self {
use libp2p_core::identity::PublicKey::*;
match key {
Ed25519(key) => {
PublicKey::Ed25519(ed25519::PublicKey::decode(&key.encode()[..]).unwrap())
}
#[cfg(not(target_arch = "wasm32"))]
Rsa(key) => PublicKey::Rsa(rsa::PublicKey::from_pkcs1(key.encode_pkcs1()).unwrap()),
Secp256k1(key) => {
PublicKey::Secp256k1(secp256k1::PublicKey::decode(&key.encode()[..]).unwrap())
impl From<libp2p_identity::PublicKey> for PublicKey {
fn from(key: libp2p_identity::PublicKey) -> Self {
fn convert_key(key: libp2p_identity::PublicKey) -> eyre::Result<PublicKey> {
match key.key_type() {
KeyType::Ed25519 => {
let pk = key.try_into_ed25519()?;
let raw_pk = ed25519::PublicKey::decode(&pk.to_bytes())?;
Ok(PublicKey::Ed25519(raw_pk))
}
_ => unimplemented!("key not supported: {:?}", key.key_type()),
}
}
convert_key(key).expect("Could not convert public key")
}
}
impl From<PublicKey> for libp2p_core::identity::PublicKey {
impl From<PublicKey> for libp2p_identity::PublicKey {
fn from(key: PublicKey) -> Self {
use libp2p_core::identity as libp2p_identity;
match key {
PublicKey::Ed25519(key) => libp2p_identity::PublicKey::Ed25519(
libp2p_identity::ed25519::PublicKey::decode(&key.encode()[..]).unwrap(),
),
#[cfg(not(target_arch = "wasm32"))]
PublicKey::Rsa(key) => libp2p_identity::PublicKey::Rsa(
libp2p_identity::rsa::PublicKey::decode_x509(&key.encode_x509()).unwrap(),
),
PublicKey::Secp256k1(key) => libp2p_identity::PublicKey::Secp256k1(
libp2p_identity::secp256k1::PublicKey::decode(&key.encode()[..]).unwrap(),
),
fn convert_key(key: PublicKey) -> eyre::Result<libp2p_identity::PublicKey> {
match key {
PublicKey::Ed25519(key) => {
let raw_pk =
libp2p_identity::ed25519::PublicKey::try_from_bytes(&key.encode())?;
let pk = libp2p_identity::PublicKey::from(raw_pk);
Ok(pk)
}
}
}
convert_key(key).expect("Could not convert key")
}
}
impl TryFrom<libp2p_core::PeerId> for PublicKey {
impl TryFrom<PeerId> for PublicKey {
type Error = DecodingError;
fn try_from(peer_id: libp2p_core::PeerId) -> Result<Self, Self::Error> {
fn try_from(peer_id: PeerId) -> Result<Self, Self::Error> {
Ok(as_public_key(&peer_id)
.ok_or_else(|| DecodingError::PublicKeyNotInlined(peer_id.to_base58()))?
.into())
@ -171,20 +138,18 @@ impl TryFrom<libp2p_core::PeerId> for PublicKey {
}
/// Convert PeerId to libp2p's PublicKey
fn as_public_key(peer_id: &PeerId) -> Option<libp2p_core::PublicKey> {
use libp2p_core::multihash;
fn as_public_key(peer_id: &PeerId) -> Option<libp2p_identity::PublicKey> {
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()
libp2p_identity::PublicKey::try_decode_protobuf(mhash.digest()).ok()
}
_ => None,
}
}
#[cfg(test)]
#[cfg(all(test, feature = "rand"))]
mod tests {
use super::*;
use crate::KeyPair;
@ -197,20 +162,12 @@ mod tests {
assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap());
}
#[test]
fn public_key_encode_decode_secp256k1() {
let kp = KeyPair::generate_secp256k1();
let pk = kp.public();
let encoded_pk = pk.encode();
assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap());
}
#[test]
fn public_key_peer_id_conversions() {
let kp = KeyPair::generate_secp256k1();
let kp = KeyPair::generate_ed25519();
let fluence_pk = kp.public();
let libp2p_pk: libp2p_core::PublicKey = fluence_pk.clone().into();
let peer_id = PeerId::from_public_key(libp2p_pk);
let libp2p_pk: libp2p_identity::PublicKey = fluence_pk.clone().into();
let peer_id = PeerId::from_public_key(&libp2p_pk);
let fluence_pk_converted = PublicKey::try_from(peer_id).unwrap();
assert_eq!(fluence_pk, fluence_pk_converted);

View File

@ -1,287 +0,0 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//! RSA keys.
use crate::error::{DecodingError, SigningError, VerificationError};
use asn1_der::{Asn1Der, Asn1DerError, DerObject, DerTag, DerValue, FromDerObject, IntoDerObject};
use lazy_static::lazy_static;
use ring::rand::SystemRandom;
use ring::signature::KeyPair;
use ring::signature::{self, RsaKeyPair, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_SHA256};
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Write},
sync::Arc,
};
use zeroize::Zeroize;
/// An RSA keypair.
#[derive(Clone)]
pub struct Keypair(Arc<RsaKeyPair>);
impl Keypair {
/// Decode an RSA keypair from a DER-encoded private key in PKCS#8 PrivateKeyInfo
/// format (i.e. unencrypted) as defined in [RFC5208].
///
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
pub fn from_pkcs8(der: &mut [u8]) -> Result<Self, DecodingError> {
let kp = RsaKeyPair::from_pkcs8(der).map_err(|_| DecodingError::Rsa)?;
der.zeroize();
Ok(Keypair(Arc::new(kp)))
}
/// Get the public key from the keypair.
pub fn public(&self) -> PublicKey {
PublicKey(self.0.public_key().as_ref().to_vec())
}
/// Sign a message with this keypair.
pub fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError> {
let mut signature = vec![0; self.0.public_modulus_len()];
let rng = SystemRandom::new();
match self.0.sign(&RSA_PKCS1_SHA256, &rng, data, &mut signature) {
Ok(()) => Ok(signature),
Err(_) => Err(SigningError::Rsa),
}
}
}
/// An RSA public key.
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PublicKey(Vec<u8>);
impl PublicKey {
/// Verify an RSA signature on a message using the public key.
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
let key = signature::UnparsedPublicKey::new(&RSA_PKCS1_2048_8192_SHA256, &self.0);
key.verify(msg, sig).map_err(|e| {
VerificationError::Rsa(
e,
bs58::encode(sig).into_string(),
bs58::encode(&self.0).into_string(),
)
})
}
/// Encode the RSA public key in DER as a PKCS#1 RSAPublicKey structure,
/// as defined in [RFC3447].
///
/// [RFC3447]: https://tools.ietf.org/html/rfc3447#appendix-A.1.1
pub fn to_pkcs1(&self) -> &[u8] {
// This is the encoding currently used in-memory, so it is trivial.
&self.0
}
pub fn from_pkcs1(pk: Vec<u8>) -> Result<Self, DecodingError> {
Ok(PublicKey(pk))
}
/// Encode the RSA public key in DER as a X.509 SubjectPublicKeyInfo structure,
/// as defined in [RFC5280].
///
/// [RFC5280]: https://tools.ietf.org/html/rfc5280#section-4.1
pub fn encode_x509(&self) -> Vec<u8> {
let spki = Asn1SubjectPublicKeyInfo {
algorithmIdentifier: Asn1RsaEncryption {
algorithm: Asn1OidRsaEncryption(),
parameters: (),
},
subjectPublicKey: Asn1SubjectPublicKey(self.clone()),
};
let mut buf = vec![0u8; spki.serialized_len()];
spki.serialize(buf.iter_mut())
.map(|_| buf)
.expect("RSA X.509 public key encoding failed.")
}
/// Decode an RSA public key from a DER-encoded X.509 SubjectPublicKeyInfo
/// structure. See also `encode_x509`.
pub fn decode_x509(pk: &[u8]) -> Result<Self, DecodingError> {
Asn1SubjectPublicKeyInfo::deserialize(pk.iter())
.map_err(|_| DecodingError::Rsa)
.map(|spki| spki.subjectPublicKey.0)
}
}
impl fmt::Debug for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let bytes = &self.0;
let mut hex = String::with_capacity(bytes.len() * 2);
for byte in bytes {
write!(hex, "{:02x}", byte).expect("Can't fail on writing to string");
}
f.debug_struct("PublicKey").field("pkcs1", &hex).finish()
}
}
//////////////////////////////////////////////////////////////////////////////
// DER encoding / decoding of public keys
//
// Primer: http://luca.ntop.org/Teaching/Appunti/asn1.html
// Playground: https://lapo.it/asn1js/
lazy_static! {
/// The DER encoding of the object identifier (OID) 'rsaEncryption' for
/// RSA public keys defined for X.509 in [RFC-3279] and used in
/// SubjectPublicKeyInfo structures defined in [RFC-5280].
///
/// [RFC-3279]: https://tools.ietf.org/html/rfc3279#section-2.3.1
/// [RFC-5280]: https://tools.ietf.org/html/rfc5280#section-4.1
static ref OID_RSA_ENCRYPTION_DER: DerObject =
DerObject {
tag: DerTag::x06,
value: DerValue {
data: vec![ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 ]
}
};
}
/// The ASN.1 OID for "rsaEncryption".
#[derive(Clone)]
struct Asn1OidRsaEncryption();
impl IntoDerObject for Asn1OidRsaEncryption {
fn into_der_object(self) -> DerObject {
OID_RSA_ENCRYPTION_DER.clone()
}
fn serialized_len(&self) -> usize {
OID_RSA_ENCRYPTION_DER.serialized_len()
}
}
impl FromDerObject for Asn1OidRsaEncryption {
fn from_der_object(o: DerObject) -> Result<Self, Asn1DerError> {
if o.tag != DerTag::x06 {
return Err(Asn1DerError::InvalidTag);
}
if o.value != OID_RSA_ENCRYPTION_DER.value {
return Err(Asn1DerError::InvalidEncoding);
}
Ok(Asn1OidRsaEncryption())
}
}
/// The ASN.1 AlgorithmIdentifier for "rsaEncryption".
#[derive(Asn1Der)]
struct Asn1RsaEncryption {
algorithm: Asn1OidRsaEncryption,
parameters: (),
}
/// The ASN.1 SubjectPublicKey inside a SubjectPublicKeyInfo,
/// i.e. encoded as a DER BIT STRING.
struct Asn1SubjectPublicKey(PublicKey);
impl IntoDerObject for Asn1SubjectPublicKey {
fn into_der_object(self) -> DerObject {
let pk_der = (self.0).0;
let mut bit_string = Vec::with_capacity(pk_der.len() + 1);
// The number of bits in pk_der is trivially always a multiple of 8,
// so there are always 0 "unused bits" signaled by the first byte.
bit_string.push(0u8);
bit_string.extend(pk_der);
DerObject::new(DerTag::x03, bit_string.into())
}
fn serialized_len(&self) -> usize {
DerObject::compute_serialized_len((self.0).0.len() + 1)
}
}
impl FromDerObject for Asn1SubjectPublicKey {
fn from_der_object(o: DerObject) -> Result<Self, Asn1DerError> {
if o.tag != DerTag::x03 {
return Err(Asn1DerError::InvalidTag);
}
let pk_der: Vec<u8> = o.value.data.into_iter().skip(1).collect();
// We don't parse pk_der further as an ASN.1 RsaPublicKey, since
// we only need the DER encoding for `verify`.
Ok(Asn1SubjectPublicKey(PublicKey(pk_der)))
}
}
/// ASN.1 SubjectPublicKeyInfo
#[derive(Asn1Der)]
#[allow(non_snake_case)]
struct Asn1SubjectPublicKeyInfo {
algorithmIdentifier: Asn1RsaEncryption,
subjectPublicKey: Asn1SubjectPublicKey,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Signature(pub Vec<u8>);
#[cfg(test)]
mod tests {
use super::*;
use quickcheck::*;
use rand::seq::SliceRandom;
use std::fmt;
const KEY1: &'static [u8] = include_bytes!("test/rsa-2048.pk8");
const KEY2: &'static [u8] = include_bytes!("test/rsa-3072.pk8");
const KEY3: &'static [u8] = include_bytes!("test/rsa-4096.pk8");
#[derive(Clone)]
struct SomeKeypair(Keypair);
impl fmt::Debug for SomeKeypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SomeKeypair")
}
}
impl Arbitrary for SomeKeypair {
fn arbitrary<G: Gen>(g: &mut G) -> SomeKeypair {
let mut key = [KEY1, KEY2, KEY3].choose(g).unwrap().to_vec();
SomeKeypair(Keypair::from_pkcs8(&mut key).unwrap())
}
}
#[test]
fn rsa_from_pkcs8() {
assert!(Keypair::from_pkcs8(&mut KEY1.to_vec()).is_ok());
assert!(Keypair::from_pkcs8(&mut KEY2.to_vec()).is_ok());
assert!(Keypair::from_pkcs8(&mut KEY3.to_vec()).is_ok());
}
#[test]
fn rsa_x509_encode_decode() {
fn prop(SomeKeypair(kp): SomeKeypair) -> Result<bool, String> {
let pk = kp.public();
PublicKey::decode_x509(&pk.encode_x509())
.map_err(|e| e.to_string())
.map(|pk2| pk2 == pk)
}
QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _);
}
#[test]
fn rsa_sign_verify() {
fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec<u8>) -> Result<bool, SigningError> {
kp.sign(&msg).map(|s| kp.public().verify(&msg, &s).is_ok())
}
QuickCheck::new()
.tests(10)
.quickcheck(prop as fn(_, _) -> _);
}
}

View File

@ -1,242 +0,0 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//! Secp256k1 keys.
use crate::error::{DecodingError, SigningError, VerificationError};
use asn1_der::{DerObject, FromDerObject};
use core::fmt;
use libsecp256k1::Message;
use rand::RngCore;
use serde::de::Error as SerdeError;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};
use sha2::{Digest as ShaDigestTrait, Sha256};
use zeroize::Zeroize;
/// A Secp256k1 keypair.
#[derive(Clone)]
pub struct Keypair {
secret: SecretKey,
public: PublicKey,
}
impl Keypair {
/// Generate a new sec256k1 `Keypair`.
pub fn generate() -> Self {
Keypair::from(SecretKey::generate())
}
/// Get the public key of this keypair.
pub fn public(&self) -> &PublicKey {
&self.public
}
/// Get the secret key of this keypair.
pub fn secret(&self) -> &SecretKey {
&self.secret
}
}
impl fmt::Debug for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Keypair")
.field("public", &self.public)
.finish()
}
}
/// Promote a Secp256k1 secret key into a keypair.
impl From<SecretKey> for Keypair {
fn from(secret: SecretKey) -> Self {
let public = PublicKey(libsecp256k1::PublicKey::from_secret_key(&secret.0));
Keypair { secret, public }
}
}
/// Demote a Secp256k1 keypair into a secret key.
impl From<Keypair> for SecretKey {
fn from(kp: Keypair) -> Self {
kp.secret
}
}
/// A Secp256k1 secret key.
#[derive(Clone)]
pub struct SecretKey(libsecp256k1::SecretKey);
impl fmt::Debug for SecretKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SecretKey")
}
}
impl SecretKey {
/// Generate a new Secp256k1 secret key.
pub fn generate() -> Self {
let mut r = rand::thread_rng();
let mut b = [0; libsecp256k1::util::SECRET_KEY_SIZE];
// This is how it is done in `secp256k1::SecretKey::random` which
// we do not use here because it uses `rand::Rng` from rand-0.4.
loop {
r.fill_bytes(&mut b);
if let Ok(k) = libsecp256k1::SecretKey::parse(&b) {
return SecretKey(k);
}
}
}
/// Create a secret key from a byte slice, zeroing the slice on success.
/// If the bytes do not constitute a valid Secp256k1 secret key, an
/// error is returned.
pub fn from_bytes(mut sk: impl AsMut<[u8]>) -> Result<Self, DecodingError> {
let sk_bytes = sk.as_mut();
let secret = libsecp256k1::SecretKey::parse_slice(&*sk_bytes)
.map_err(|_| DecodingError::Secp256k1)?;
sk_bytes.zeroize();
Ok(SecretKey(secret))
}
/// Decode a DER-encoded Secp256k1 secret key in an ECPrivateKey
/// structure as defined in [RFC5915].
///
/// [RFC5915]: https://tools.ietf.org/html/rfc5915
pub fn from_der(mut der: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
// TODO: Stricter parsing.
let der_obj = der.as_mut();
let obj: Vec<DerObject> =
FromDerObject::deserialize((&*der_obj).iter()).map_err(|_| DecodingError::Secp256k1)?;
der_obj.zeroize();
let sk_obj = obj.into_iter().nth(1).ok_or(DecodingError::Secp256k1)?;
let mut sk_bytes: Vec<u8> =
FromDerObject::from_der_object(sk_obj).map_err(|_| DecodingError::Secp256k1)?;
let sk = SecretKey::from_bytes(&mut sk_bytes)?;
sk_bytes.zeroize();
Ok(sk)
}
/// Sign a message with this secret key, producing a DER-encoded
/// ECDSA signature, as defined in [RFC3278].
///
/// [RFC3278]: https://tools.ietf.org/html/rfc3278#section-8.2
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
self.sign_hashed(Sha256::digest(msg).as_ref())
}
/// Returns the raw bytes of the secret key.
pub fn to_bytes(&self) -> [u8; 32] {
self.0.serialize()
}
/// Sign a raw message of length 256 bits with this secret key, produces a DER-encoded
/// ECDSA signature.
pub fn sign_hashed(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
let m = Message::parse_slice(msg).map_err(SigningError::Secp256k1)?;
Ok(libsecp256k1::sign(&m, &self.0)
.0
.serialize_der()
.as_ref()
.into())
}
}
/// A Secp256k1 public key.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct PublicKey(libsecp256k1::PublicKey);
impl PublicKey {
/// Verify the Secp256k1 signature on a message using the public key.
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
self.verify_hashed(Sha256::digest(msg).as_ref(), sig)
}
/// Verify the Secp256k1 DER-encoded signature on a raw 256-bit message using the public key.
pub fn verify_hashed(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> {
Message::parse_slice(msg)
.and_then(|m| {
libsecp256k1::Signature::parse_der(sig)
.map(|s| libsecp256k1::verify(&m, &s, &self.0))
})
.map_err(|e| {
VerificationError::Secp256k1(
e,
bs58::encode(sig).into_string(),
bs58::encode(self.0.serialize_compressed()).into_string(),
)
})
.map(|_| ())
}
/// Encode the public key in compressed form, i.e. with one coordinate
/// represented by a single bit.
pub fn encode(&self) -> [u8; 33] {
self.0.serialize_compressed()
}
/// Encode the public key in uncompressed form.
pub fn encode_uncompressed(&self) -> [u8; 65] {
self.0.serialize()
}
/// Decode a public key from a byte slice in the the format produced
/// by `encode`.
pub fn decode(bytes: &[u8]) -> Result<Self, DecodingError> {
libsecp256k1::PublicKey::parse_slice(bytes, Some(libsecp256k1::PublicKeyFormat::Compressed))
.map_err(|_| DecodingError::Secp256k1)
.map(PublicKey)
}
}
impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
SerdeBytes::new(self.encode().to_vec().as_slice()).serialize(serializer)
}
}
impl<'d> Deserialize<'d> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'d>,
{
let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
PublicKey::decode(bytes.as_slice()).map_err(SerdeError::custom)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Signature(pub Vec<u8>);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn secp256k1_secret_from_bytes() {
let sk1 = SecretKey::generate();
let mut sk_bytes = [0; 32];
sk_bytes.copy_from_slice(&sk1.0.serialize()[..]);
let sk2 = SecretKey::from_bytes(&mut sk_bytes).unwrap();
assert_eq!(sk1.0.serialize(), sk2.0.serialize());
assert_eq!(sk_bytes, [0; 32]);
}
}

View File

@ -16,18 +16,12 @@
use crate::ed25519;
use crate::error::DecodingError;
use crate::key_pair::KeyFormat;
#[cfg(not(target_arch = "wasm32"))]
use crate::rsa;
use crate::secp256k1;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub enum Signature {
Ed25519(ed25519::Signature),
#[cfg(not(target_arch = "wasm32"))]
Rsa(rsa::Signature),
Secp256k1(secp256k1::Signature),
}
pub struct RawSignature {
@ -40,9 +34,6 @@ impl Signature {
use Signature::*;
match self {
Ed25519(_) => KeyFormat::Ed25519.into(),
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => KeyFormat::Rsa.into(),
Secp256k1(_) => KeyFormat::Secp256k1.into(),
}
}
@ -54,9 +45,6 @@ impl Signature {
match self {
Ed25519(sig) => result.extend(sig.0.clone()),
#[cfg(not(target_arch = "wasm32"))]
Rsa(sig) => result.extend(sig.0.clone()),
Secp256k1(sig) => result.extend(sig.0.clone()),
}
result
@ -66,11 +54,6 @@ impl Signature {
pub fn decode(bytes: Vec<u8>) -> Result<Self, DecodingError> {
match KeyFormat::try_from(bytes[0])? {
KeyFormat::Ed25519 => Ok(Signature::Ed25519(ed25519::Signature(bytes[1..].to_vec()))),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => Ok(Signature::Rsa(rsa::Signature(bytes[1..].to_vec()))),
KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature(
bytes[1..].to_vec(),
))),
}
}
@ -79,9 +62,6 @@ impl Signature {
match self {
Ed25519(sig) => &sig.0,
#[cfg(not(target_arch = "wasm32"))]
Rsa(sig) => &sig.0,
Secp256k1(sig) => &sig.0,
}
}
@ -90,9 +70,6 @@ impl Signature {
match self {
Ed25519(_) => KeyFormat::Ed25519,
#[cfg(not(target_arch = "wasm32"))]
Rsa(_) => KeyFormat::Rsa,
Secp256k1(_) => KeyFormat::Secp256k1,
}
}
@ -106,9 +83,6 @@ impl Signature {
pub fn from_bytes(key_format: KeyFormat, bytes: Vec<u8>) -> Self {
match key_format {
KeyFormat::Ed25519 => Signature::Ed25519(ed25519::Signature(bytes)),
#[cfg(not(target_arch = "wasm32"))]
KeyFormat::Rsa => Signature::Rsa(rsa::Signature(bytes)),
KeyFormat::Secp256k1 => Signature::Secp256k1(secp256k1::Signature(bytes)),
}
}
}
@ -121,19 +95,10 @@ mod tests {
fn signature_encode_decode() {
let bytes: Vec<u8> = (0..10).collect();
let ed25519_sig = Signature::Ed25519(crate::ed25519::Signature(bytes.clone()));
let secp256k1_sig = Signature::Secp256k1(crate::secp256k1::Signature(bytes.clone()));
#[cfg(not(target_arch = "wasm32"))]
let rsa_sig = Signature::Rsa(crate::rsa::Signature(bytes.clone()));
assert_eq!(
Signature::decode(ed25519_sig.encode()).unwrap(),
ed25519_sig
);
assert_eq!(
Signature::decode(secp256k1_sig.encode()).unwrap(),
secp256k1_sig
);
#[cfg(not(target_arch = "wasm32"))]
assert_eq!(Signature::decode(rsa_sig.encode()).unwrap(), rsa_sig);
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +1,4 @@
[toolchain]
channel = "nightly-2022-12-06"
targets = [ "x86_64-apple-darwin", "wasm32-wasi", "wasm32-unknown-unknown", "x86_64-unknown-linux-gnu" ]
components = [ "rustfmt", "clippy" ]

View File

@ -4,6 +4,117 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.4.1 to 0.4.2
* fluence-keypair bumped from 0.10.0 to 0.10.1
## [0.4.7](https://github.com/fluencelabs/trust-graph/compare/trust-graph-wasm-v0.4.6...trust-graph-wasm-v0.4.7) (2023-07-04)
### Bug Fixes
* **deps:** update rust crate marine-rs-sdk-test to 0.10.0 ([#106](https://github.com/fluencelabs/trust-graph/issues/106)) ([725d3f8](https://github.com/fluencelabs/trust-graph/commit/725d3f8f48b3bf1ed8605e9ba2da5c966a145f0d))
### Dependencies
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.4.6 to 0.4.7
* fluence-keypair bumped from 0.10.2 to 0.10.3
## [0.4.6](https://github.com/fluencelabs/trust-graph/compare/trust-graph-wasm-v0.4.5...trust-graph-wasm-v0.4.6) (2023-06-30)
### Reverts
* release master ([#110](https://github.com/fluencelabs/trust-graph/issues/110)) ([d80a43b](https://github.com/fluencelabs/trust-graph/commit/d80a43bcff721aff8fadf3d2d5c252804ce27a6c))
### Dependencies
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.4.5 to 0.4.6
* fluence-keypair bumped from 0.10.1 to 0.10.2
## [0.4.5](https://github.com/fluencelabs/trust-graph/compare/trust-graph-wasm-v0.4.4...trust-graph-wasm-v0.4.5) (2023-05-09)
### Miscellaneous Chores
* **trust-graph-wasm:** Synchronize trust-graph, wasm and api versions
### Dependencies
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.4.4 to 0.4.5
## [0.4.4](https://github.com/fluencelabs/trust-graph/compare/trust-graph-wasm-v0.4.3...trust-graph-wasm-v0.4.4) (2023-05-09)
### Miscellaneous Chores
* **trust-graph-wasm:** Synchronize trust-graph, wasm and api versions
### Dependencies
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.4.3 to 0.4.4
## [0.4.3](https://github.com/fluencelabs/trust-graph/compare/trust-graph-wasm-v0.4.2...trust-graph-wasm-v0.4.3) (2023-05-08)
### Miscellaneous Chores
* **trust-graph-wasm:** Synchronize trust-graph, wasm and api versions
### Dependencies
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.4.2 to 0.4.3
## [0.4.1](https://github.com/fluencelabs/trust-graph/compare/trust-graph-wasm-v0.4.0...trust-graph-wasm-v0.4.1) (2023-04-13)
### Bug Fixes
* **deps:** Add trust-graph to workspace and bump sqlite-wasm version ([#87](https://github.com/fluencelabs/trust-graph/issues/87)) ([da38a41](https://github.com/fluencelabs/trust-graph/commit/da38a41ba727a14774a71bba6612b1bf1f498db9))
### Dependencies
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.4.0 to 0.4.1
## [0.4.0](https://github.com/fluencelabs/trust-graph/compare/trust-graph-wasm-v0.3.2...trust-graph-wasm-v0.4.0) (2023-03-15)
### ⚠ BREAKING CHANGES
* **deps:** update libp2p to 0.39.1 and other deps ([#77](https://github.com/fluencelabs/trust-graph/issues/77))
### Features
* **deps:** update libp2p to 0.39.1 and other deps ([#77](https://github.com/fluencelabs/trust-graph/issues/77)) ([080503d](https://github.com/fluencelabs/trust-graph/commit/080503dcfa2ecf8d09167ff9fe7f750fadf49035))
* **keypair:** add KeyPair::from_secret_key ([#50](https://github.com/fluencelabs/trust-graph/issues/50)) ([a6ce8d9](https://github.com/fluencelabs/trust-graph/commit/a6ce8d9eee20e1ea24eb27c38ac6df6d878292ae))
### Dependencies
* The following workspace dependencies were updated
* dependencies
* trust-graph bumped from 0.3.0 to 0.4.0
* fluence-keypair bumped from 0.9.0 to 0.10.0
## [Unreleased]
## [0.3.1] - 2022-10-06

View File

@ -1,8 +1,8 @@
[package]
name = "trust-graph-wasm"
version = "0.3.1"
version = "0.4.7"
authors = ["Fluence Labs"]
edition = "2018"
edition = "2021"
description = "trust graph wasm"
license = "Apache-2.0"
publish = false
@ -12,28 +12,25 @@ name = "trust-graph"
path = "src/main.rs"
[dependencies]
trust-graph = { version = "0.3.0", path = "../." }
fluence-keypair = { version = "0.8.1", path = "../keypair" }
marine-rs-sdk = { version = "0.6.14", features = ["logger"] }
marine-sqlite-connector = "0.5.2"
trust-graph = { version = "0.4.7", path = "../trust-graph" }
fluence-keypair = { version = "0.10.3", path = "../keypair" }
marine-rs-sdk = { version = "0.7.1", features = ["logger"] }
marine-sqlite-connector = "0.8.0"
libp2p-core = { workspace = true }
libp2p-identity = { workspace = true }
log = "0.4.8"
anyhow = "1.0.31"
boolinator = "2.4.0"
once_cell = "1.4.1"
parking_lot = "0.11.1"
serde_json = "1.0"
bs58 = "0.3.1"
rmp-serde = "0.15.0"
bs58 = "0.4.0"
rmp-serde = "1.1.1"
bincode = "1.3.1"
serde_bencode = "^0.2.3"
thiserror = "1.0.23"
[dev-dependencies]
marine-rs-sdk-test = "0.4.0"
rusqlite = "0.26.1"
marine-rs-sdk-test = "0.9.1"
rusqlite = "0.28.0"
[build-dependencies]
marine-rs-sdk-test = "0.4.0"
marine-rs-sdk-test = "0.9.1"

View File

@ -5,12 +5,10 @@ modules_dir = "artifacts/"
logger_enabled = true
[module.wasi]
preopened_files = ["/tmp"]
mapped_dirs = { "tmp" = "/tmp" }
mapped_dirs = { "/tmp" = "data" }
[[module]]
name = "trust-graph"
logger_enabled = true
[module.wasi]
preopened_files = ["/tmp"]
mapped_dirs = { "tmp" = "/tmp" }
mapped_dirs = { "/tmp" = "data" }

View File

@ -13,7 +13,7 @@ mkdir -p artifacts
cp ../target/wasm32-wasi/release/trust-graph.wasm artifacts/
# download SQLite 3 to use in tests
curl -L https://github.com/fluencelabs/sqlite/releases/download/v0.15.0_w/sqlite3.wasm -o artifacts/sqlite3.wasm
curl -sS -L https://github.com/fluencelabs/sqlite/releases/download/sqlite-wasm-v0.18.1/sqlite3.wasm -o artifacts/sqlite3.wasm
# # generate Aqua bindings
# marine aqua artifacts/trust-graph.wasm -s TrustGraph -i trust-graph > ../aqua/trust-graph.aqua
# generate Aqua bindings
marine aqua artifacts/trust-graph.wasm -s TrustGraph -i trust-graph > ../aqua/trust-graph.aqua

View File

@ -1,7 +1,7 @@
use crate::dto::DtoConversionError::PeerIdDecodeError;
use fluence_keypair::error::DecodingError;
use fluence_keypair::{KeyFormat, PublicKey, Signature};
use libp2p_core::PeerId;
use libp2p_identity::PeerId;
use marine_rs_sdk::marine;
use std::convert::TryFrom;
use std::str::FromStr;
@ -78,7 +78,7 @@ impl TryFrom<Trust> for trust_graph::Trust {
fn try_from(t: Trust) -> Result<Self, Self::Error> {
let issued_for = PublicKey::try_from(
PeerId::from_str(&t.issued_for).map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
PeerId::from_str(&t.issued_for).map_err(|e| PeerIdDecodeError(format!("{e:?}")))?,
)
.map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?;
let signature = bs58::decode(&t.signature).into_vec()?;
@ -132,11 +132,11 @@ impl TryFrom<Revocation> for trust_graph::Revocation {
fn try_from(r: Revocation) -> Result<Self, Self::Error> {
let revoked_pk = PublicKey::try_from(
PeerId::from_str(&r.revoked_peer_id)
.map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
.map_err(|e| PeerIdDecodeError(format!("{e:?}")))?,
)
.map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?;
let revoked_by_pk = PublicKey::try_from(
PeerId::from_str(&r.revoked_by).map_err(|e| PeerIdDecodeError(format!("{:?}", e)))?,
PeerId::from_str(&r.revoked_by).map_err(|e| PeerIdDecodeError(format!("{e:?}")))?,
)
.map_err(|e| DtoConversionError::PeerIdDecodeError(e.to_string()))?;
let signature = bs58::decode(&r.signature).into_vec()?;

View File

@ -13,31 +13,10 @@ mod results;
mod service_api;
mod storage_impl;
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 fn main() {
_initialize(); // As __wasm_call_ctors still does necessary work, we call it at the start of the module
WasmLoggerBuilder::new()
.with_log_level(log::LevelFilter::Trace)
.build()

View File

@ -18,7 +18,7 @@ use crate::error::ServiceError::*;
use crate::storage_impl::{SQLiteStorage, DB_PATH};
use crate::TRUSTED_TIMESTAMP;
use fluence_keypair::PublicKey;
use libp2p_core::PeerId;
use libp2p_identity::PeerId;
use marine_rs_sdk::CallParameters;
use std::cell::RefCell;
use std::convert::TryFrom;
@ -27,6 +27,7 @@ use std::str::FromStr;
use trust_graph::TrustGraph;
/// Check timestamps are generated on the current host with builtin ("peer" "timestamp_sec")
#[allow(clippy::unnecessary_lazy_evaluations)]
pub(crate) fn check_timestamp_tetraplets(
call_parameters: &CallParameters,
arg_number: usize,
@ -41,12 +42,12 @@ pub(crate) fn check_timestamp_tetraplets(
(TRUSTED_TIMESTAMP.eq(&(&tetraplet.service_id, &tetraplet.function_name))
&& tetraplet.peer_pk == call_parameters.host_id)
.then(|| ())
.ok_or_else(|| InvalidTimestampTetraplet(format!("{:?}", tetraplet)))
.ok_or_else(|| InvalidTimestampTetraplet(format!("{tetraplet:?}")))
}
fn parse_peer_id(peer_id: String) -> Result<PeerId, ServiceError> {
libp2p_core::PeerId::from_str(&peer_id)
.map_err(|e| ServiceError::PeerIdParseError(format!("{:?}", e)))
libp2p_identity::PeerId::from_str(&peer_id)
.map_err(|e| ServiceError::PeerIdParseError(format!("{e:?}")))
}
thread_local!(static INSTANCE: RefCell<TrustGraph<SQLiteStorage>> = RefCell::new(TrustGraph::new(

View File

@ -17,7 +17,7 @@ impl From<Result<(), ServiceError>> for InsertResult {
},
Err(e) => InsertResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
},
}
}
@ -44,7 +44,7 @@ impl From<Result<(u32, String), ServiceError>> for WeightResult {
success: false,
weight: 0u32,
peer_id: "".to_string(),
error: format!("{}", e),
error: format!("{e}"),
},
}
}
@ -68,7 +68,7 @@ impl From<Result<Vec<Certificate>, ServiceError>> for AllCertsResult {
Err(e) => AllCertsResult {
success: false,
certificates: vec![],
error: format!("{}", e),
error: format!("{e}"),
},
}
}
@ -89,7 +89,7 @@ impl From<Result<(), ServiceError>> for SetRootResult {
},
Err(e) => SetRootResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
},
}
}
@ -112,7 +112,7 @@ impl From<Result<Vec<u8>, ServiceError>> for GetTrustBytesResult {
},
Err(e) => GetTrustBytesResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
result: vec![],
},
}
@ -136,7 +136,7 @@ impl From<Result<Trust, ServiceError>> for IssueTrustResult {
},
Err(e) => IssueTrustResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
trust: Trust::default(),
},
}
@ -158,7 +158,7 @@ impl From<Result<(), ServiceError>> for VerifyTrustResult {
},
Err(e) => VerifyTrustResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
},
}
}
@ -181,7 +181,7 @@ impl From<Result<u32, ServiceError>> for AddTrustResult {
},
Err(e) => AddTrustResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
weight: u32::default(),
},
}
@ -205,7 +205,7 @@ impl From<Result<Vec<u8>, ServiceError>> for GetRevokeBytesResult {
},
Err(e) => GetRevokeBytesResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
result: vec![],
},
}
@ -229,7 +229,7 @@ impl From<Result<Revocation, ServiceError>> for IssueRevocationResult {
},
Err(e) => IssueRevocationResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
revocation: Revocation::default(),
},
}
@ -251,7 +251,7 @@ impl From<Result<(), ServiceError>> for RevokeResult {
},
Err(e) => RevokeResult {
success: false,
error: format!("{}", e),
error: format!("{e}"),
},
}
}
@ -275,7 +275,7 @@ impl From<Result<Vec<Revocation>, ServiceError>> for ExportRevocationsResult {
Err(e) => ExportRevocationsResult {
success: false,
revocations: vec![],
error: format!("{}", e),
error: format!("{e}"),
},
}
}

View File

@ -100,7 +100,7 @@ impl SQLiteStorage {
.cursor();
cursor.bind(&[
Value::String(format!("{}", issued_for)),
Value::String(format!("{issued_for}")),
Value::Integer(relation_type),
])?;
let mut relations: Vec<TrustRelation> = vec![];
@ -206,8 +206,8 @@ impl Storage for SQLiteStorage {
.cursor();
cursor.bind(&[
Value::String(format!("{}", issued_by)),
Value::String(format!("{}", issued_for)),
Value::String(format!("{issued_by}")),
Value::String(format!("{issued_for}")),
])?;
if let Some(row) = cursor.next()? {
@ -281,7 +281,7 @@ impl Storage for SQLiteStorage {
.prepare("SELECT public_key, weight_factor FROM roots WHERE public_key = ?")?
.cursor();
cursor.bind(&[Value::String(format!("{}", pk))])?;
cursor.bind(&[Value::String(format!("{pk}"))])?;
if let Some(row) = cursor.next()? {
let w = u32::try_from(row[1].as_integer().ok_or(WeightFactorConversionDB)?)
@ -304,7 +304,7 @@ impl Storage for SQLiteStorage {
.cursor();
cursor.bind(&[
Value::String(format!("{}", pk)),
Value::String(format!("{pk}")),
Value::Integer(i64::from(weight_factor)),
])?;

View File

@ -18,18 +18,18 @@
mod service_tests {
marine_rs_sdk_test::include_test_env!("/marine_test_env.rs");
use crate::error::ServiceError;
use crate::storage_impl::DB_PATH;
use crate::TRUSTED_TIMESTAMP;
use fluence_keypair::KeyPair;
use libp2p_core::PeerId;
use libp2p_identity::PeerId;
use marine_rs_sdk::{CallParameters, SecurityTetraplet};
use marine_test_env::trust_graph::{Certificate, Revocation, ServiceInterface, Trust};
use rusqlite::Connection;
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
static HOST_ID: &str = "some_host_id";
static TEST_DB_PATH: &str = "data/trust-graph.sqlite";
struct Auth {
issuer: PeerId,
trust: Trust,
@ -55,12 +55,7 @@ mod service_tests {
}
fn clear_env() {
let connection = Connection::open(DB_PATH).unwrap();
connection
.execute("DELETE FROM trust_relations", [])
.unwrap();
connection.execute("DELETE FROM roots", []).unwrap();
std::fs::remove_file(TEST_DB_PATH).unwrap_or_default();
}
fn get_correct_timestamp_cp(arg_number: usize) -> CallParameters {
@ -445,32 +440,32 @@ mod service_tests {
let mut trust_graph = marine_test_env::trust_graph::ServiceInterface::new();
clear_env();
let peerA_kp = KeyPair::generate_ed25519();
let peer_a_kp = KeyPair::generate_ed25519();
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, &peer_a_kp, cur_time, cur_time + 9999, 10);
let peerB_kp = KeyPair::generate_ed25519();
let peer_b_kp = KeyPair::generate_ed25519();
add_trust(
&mut trust_graph,
&peerA_kp,
&peerB_kp.get_peer_id(),
&peer_a_kp,
&peer_b_kp.get_peer_id(),
cur_time,
cur_time + 99999,
);
let weight = get_weight(&mut trust_graph, peerB_kp.get_peer_id(), cur_time);
let weight = get_weight(&mut trust_graph, peer_b_kp.get_peer_id(), cur_time);
assert_ne!(weight, 0u32);
cur_time += 1;
// A revokes B and cancels trust
revoke(
&mut trust_graph,
&peerA_kp,
&peerB_kp.get_peer_id(),
&peer_a_kp,
&peer_b_kp.get_peer_id(),
cur_time,
);
let weight = get_weight(&mut trust_graph, peerB_kp.get_peer_id(), cur_time);
let weight = get_weight(&mut trust_graph, peer_b_kp.get_peer_id(), cur_time);
assert_eq!(weight, 0u32);
}

91
trust-graph/CHANGELOG.md Normal file
View File

@ -0,0 +1,91 @@
# Changelog
* The following workspace dependencies were updated
* dependencies
* fluence-keypair bumped from 0.10.0 to 0.10.1
## [0.4.7](https://github.com/fluencelabs/trust-graph/compare/trust-graph-v0.4.6...trust-graph-v0.4.7) (2023-07-04)
### Miscellaneous Chores
* **trust-graph:** Synchronize trust-graph, wasm and api versions
### Dependencies
* The following workspace dependencies were updated
* dependencies
* fluence-keypair bumped from 0.10.2 to 0.10.3
## [0.4.6](https://github.com/fluencelabs/trust-graph/compare/trust-graph-v0.4.5...trust-graph-v0.4.6) (2023-06-30)
### Bug Fixes
* **deps:** update rust crate derivative to 2.2.0 ([2001f90](https://github.com/fluencelabs/trust-graph/commit/2001f900fa13a949decd513d8cbe15e3f006a7fc))
* **deps:** update rust crate derivative to 2.2.0 ([#88](https://github.com/fluencelabs/trust-graph/issues/88)) ([2001f90](https://github.com/fluencelabs/trust-graph/commit/2001f900fa13a949decd513d8cbe15e3f006a7fc))
### Reverts
* release master ([#110](https://github.com/fluencelabs/trust-graph/issues/110)) ([d80a43b](https://github.com/fluencelabs/trust-graph/commit/d80a43bcff721aff8fadf3d2d5c252804ce27a6c))
### Dependencies
* The following workspace dependencies were updated
* dependencies
* fluence-keypair bumped from 0.10.1 to 0.10.2
## [0.4.5](https://github.com/fluencelabs/trust-graph/compare/trust-graph-v0.4.4...trust-graph-v0.4.5) (2023-05-09)
### Features
* dummy to trigger release ([#101](https://github.com/fluencelabs/trust-graph/issues/101)) ([1a26a68](https://github.com/fluencelabs/trust-graph/commit/1a26a6809ea9a90ca8ff3829a76257779a8767d5))
## [0.4.4](https://github.com/fluencelabs/trust-graph/compare/trust-graph-v0.4.3...trust-graph-v0.4.4) (2023-05-09)
### Features
* fix trust-graph package ([#98](https://github.com/fluencelabs/trust-graph/issues/98)) ([a8fdb44](https://github.com/fluencelabs/trust-graph/commit/a8fdb4472ef1676724e4bfab1b4419f07faae2d9))
## [0.4.3](https://github.com/fluencelabs/trust-graph/compare/trust-graph-v0.4.2...trust-graph-v0.4.3) (2023-05-08)
### Features
* dummy change for release ([#95](https://github.com/fluencelabs/trust-graph/issues/95)) ([b6df3fe](https://github.com/fluencelabs/trust-graph/commit/b6df3fe5484b0adcad0c88abe170317a837142b3))
## [0.4.1](https://github.com/fluencelabs/trust-graph/compare/trust-graph-v0.4.0...trust-graph-v0.4.1) (2023-04-13)
### Miscellaneous Chores
* **trust-graph:** Synchronize trust-graph, wasm and api versions
## [0.4.0](https://github.com/fluencelabs/trust-graph/compare/trust-graph-v0.3.2...trust-graph-v0.4.0) (2023-03-15)
### ⚠ BREAKING CHANGES
* **deps:** update libp2p to 0.39.1 and other deps ([#77](https://github.com/fluencelabs/trust-graph/issues/77))
### Features
* **deps:** update libp2p to 0.39.1 and other deps ([#77](https://github.com/fluencelabs/trust-graph/issues/77)) ([080503d](https://github.com/fluencelabs/trust-graph/commit/080503dcfa2ecf8d09167ff9fe7f750fadf49035))
* **keypair:** add KeyPair::from_secret_key ([#50](https://github.com/fluencelabs/trust-graph/issues/50)) ([a6ce8d9](https://github.com/fluencelabs/trust-graph/commit/a6ce8d9eee20e1ea24eb27c38ac6df6d878292ae))
### Bug Fixes
* **deps:** Update libp2p-core to 0.38 ([#51](https://github.com/fluencelabs/trust-graph/issues/51)) ([015422e](https://github.com/fluencelabs/trust-graph/commit/015422efcce41530a6cd84a25091598bc459d2e6))
### Dependencies
* The following workspace dependencies were updated
* dependencies
* fluence-keypair bumped from 0.9.0 to 0.10.0

22
trust-graph/Cargo.toml Normal file
View File

@ -0,0 +1,22 @@
[package]
name = "trust-graph"
version = "0.4.7"
authors = ["Fluence Labs"]
edition = "2021"
description = "trust graph"
license = "Apache-2.0"
repository = "https://github.com/fluencelabs/trust-graph"
[dependencies]
serde = { version = "1.0.118", features = ["derive"] }
fluence-keypair = { path = "../keypair", version = "0.10.3" }
bs58 = "0.4.0"
failure = "0.1.6"
log = "0.4.11"
ref-cast = "1.0.2"
derivative = "2.2.0"
thiserror = "1.0.23"
sha2 = "0.10.6"
nonempty = "0.8.1"
rand = "0.8.5"

View File

@ -160,8 +160,8 @@ impl Certificate {
) -> Result<Self, CertificateError> {
if expires_at.lt(&issued_at) {
return Err(ExpirationError {
expires_at: format!("{:?}", expires_at),
issued_at: format!("{:?}", issued_at),
expires_at: format!("{expires_at:?}"),
issued_at: format!("{issued_at:?}"),
});
}

View File

@ -35,7 +35,7 @@ mod single {
{
let str = String::deserialize(deserializer)?;
Certificate::from_str(&str)
.map_err(|e| Error::custom(format!("certificate deserialization failed for {:?}", e)))
.map_err(|e| Error::custom(format!("certificate deserialization failed for {e:?}")))
}
}
@ -63,7 +63,7 @@ pub mod vec {
v.into_iter()
.map(|e| {
Certificate::from_str(&e).map_err(|e| {
Error::custom(format!("certificate deserialization failed for {:?}", e))
Error::custom(format!("certificate deserialization failed for {e:?}"))
})
})
.collect()

View File

@ -5,6 +5,6 @@ pub fn current_time() -> Duration {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as u64,
.as_secs(),
)
}

View File

@ -120,10 +120,10 @@ impl<'de> serde::Deserialize<'de> for PublicKeyHashable {
{
bs58::decode(s)
.into_vec()
.map_err(|err| Error::custom(format!("Invalid string '{}': {}", s, err)))
.map_err(|err| Error::custom(format!("Invalid string '{s}': {err}")))
.and_then(|v| self.visit_bytes(v.as_slice()))
.map_err(|err: E| {
Error::custom(format!("Parsed string '{}' as base58, but {}", s, err))
Error::custom(format!("Parsed string '{s}' as base58, but {err}"))
})
}
@ -132,7 +132,7 @@ impl<'de> serde::Deserialize<'de> for PublicKeyHashable {
E: Error,
{
let pk = PublicKey::decode(b)
.map_err(|err| Error::custom(format!("Invalid bytes {:?}: {}", b, err)))?;
.map_err(|err| Error::custom(format!("Invalid bytes {b:?}: {err}")))?;
Ok(PublicKeyHashable::from(pk))
}
}

View File

@ -75,7 +75,7 @@ impl Revocation {
let pk_bytes = &pk.encode();
metadata.push(pk_bytes.len() as u8);
metadata.extend(pk_bytes);
metadata.extend_from_slice(&(revoked_at.as_secs() as u64).to_le_bytes());
metadata.extend_from_slice(&revoked_at.as_secs().to_le_bytes());
sha2::Sha256::digest(&metadata).to_vec()
}

View File

@ -144,8 +144,8 @@ impl Trust {
pub fn signature_bytes(pk: &PublicKey, expires_at: Duration, issued_at: Duration) -> Vec<u8> {
let pk_encoded = pk.encode();
let expires_at_encoded: [u8; EXPIRATION_LEN] = (expires_at.as_secs() as u64).to_le_bytes();
let issued_at_encoded: [u8; ISSUED_LEN] = (issued_at.as_secs() as u64).to_le_bytes();
let expires_at_encoded: [u8; EXPIRATION_LEN] = expires_at.as_secs().to_le_bytes();
let issued_at_encoded: [u8; ISSUED_LEN] = issued_at.as_secs().to_le_bytes();
let mut metadata = Vec::new();
metadata.extend(pk_encoded);
@ -165,8 +165,8 @@ impl Trust {
vec.append(&mut issued_for);
vec.push(signature.len() as u8);
vec.append(&mut signature);
vec.extend_from_slice(&(self.expires_at.as_secs() as u64).to_le_bytes());
vec.extend_from_slice(&(self.issued_at.as_secs() as u64).to_le_bytes());
vec.extend_from_slice(&self.expires_at.as_secs().to_le_bytes());
vec.extend_from_slice(&self.issued_at.as_secs().to_le_bytes());
vec
}
@ -260,13 +260,10 @@ impl ToString for Trust {
fn to_string(&self) -> String {
let issued_for = bs58::encode(self.issued_for.encode()).into_string();
let signature = bs58::encode(self.signature.encode()).into_string();
let expires_at = (self.expires_at.as_secs() as u64).to_string();
let issued_at = (self.issued_at.as_secs() as u64).to_string();
let expires_at = self.expires_at.as_secs().to_string();
let issued_at = self.issued_at.as_secs().to_string();
format!(
"{}\n{}\n{}\n{}",
issued_for, signature, expires_at, issued_at
)
format!("{issued_for}\n{signature}\n{expires_at}\n{issued_at}")
}
}

View File

@ -90,7 +90,7 @@ impl<T: StorageError + 'static> From<T> for TrustGraphError {
impl From<TrustGraphError> for String {
fn from(err: TrustGraphError) -> Self {
format!("{}", err)
format!("{err}")
}
}
@ -374,8 +374,7 @@ where
// Certificate with one trust means nothing, gotta be a bug. Checking for it here.
debug_assert!(
c.chain.len() > 1,
"certificate with chain of len 1 arose: {:#?}",
c
"certificate with chain of len 1 arose: {c:#?}",
);
c.chain.len() > 1
})