Compare commits

..

4 Commits

Author SHA1 Message Date
Jędrzej Stuczyński 7f840b889f Merge branch 'feature/optional-contract-addresses' into temp-jstuczyn-branch 2022-01-20 17:32:57 +00:00
Jędrzej Stuczyński 5cd67b22b3 Made contract addresses for query NymdClient construction optional
Similarly as it is the case when creating SigningNymdClient
2022-01-20 17:03:16 +00:00
Jędrzej Stuczyński 25c6748ae9 Cargo fmt 2022-01-20 15:52:32 +00:00
Jędrzej Stuczyński 78d2ffa923 Introduced RPC query for total token supply 2022-01-20 15:47:46 +00:00
464 changed files with 9199 additions and 16621 deletions
+2 -2
View File
@@ -15,8 +15,8 @@
* @futurechimp @mmsinclair
# Rust rules:
*.rs @durch @futurechimp @jstuczyn @neacsu @octol
Cargo.* @durch @futurechimp @jstuczyn @neacsu @octol
*.rs @durch @futurechimp @jstuczyn @neacsu
Cargo.* @durch @futurechimp @jstuczyn @neacsu
# JS rules:
*.js @mmsinclair @fmtabbara @Aid19801
+31 -4
View File
@@ -9,11 +9,28 @@ on:
- 'explorer/**'
jobs:
matrix_prep:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from build_matrix_includes.json
- uses: actions/checkout@v2
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/build_matrix_includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
build:
runs-on: [ self-hosted, custom-linux-exoscale ]
needs: matrix_prep
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.os == 'windows-latest' }}
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-latest'
- name: Check out repository code
uses: actions/checkout@v2
@@ -22,7 +39,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy
@@ -46,16 +63,25 @@ jobs:
- uses: actions-rs/clippy-check@v1
name: Clippy checks
# if: matrix.os == 'ubuntu-latest' && matrix.rust == 'stable'
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: -- -D warnings
# COCONUT stuff
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
@@ -70,6 +96,7 @@ jobs:
- name: Run clippy with coconut enabled
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --features=coconut -- -D warnings
args: --features=coconut -- -D warnings
+33 -2
View File
@@ -10,10 +10,41 @@
"rust":"stable",
"runOnEvent":"pull_request"
},
{
"os":"macos-latest",
"rust":"stable",
"runOnEvent":"pull_request"
},
{
"os":"ubuntu-latest",
"rust":"beta",
"runOnEvent":"pull_request"
},
{
"os":"windows-latest",
"rust":"beta",
"runOnEvent":"pull_request"
},
{
"os":"macos-latest",
"rust":"beta",
"runOnEvent":"pull_request"
},
{
"os":"ubuntu-latest",
"rust":"nightly",
"runOnEvent":"pull_request"
},
{
"os":"windows-latest",
"rust":"nightly",
"runOnEvent":"pull_request"
},
{
"os":"macos-latest",
"rust":"nightly",
"runOnEvent":"pull_request"
}
]
]
+2 -3
View File
@@ -41,10 +41,9 @@ jobs:
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
working-directory: .github/workflows/support-files/messages
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: network-explorer
NYM_PROJECT_NAME: "Network Explorer"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "network-explorer-${{ env.GITHUB_REF_SLUG }}"
@@ -57,4 +56,4 @@ jobs:
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
args: .github/workflows/support-files/messages/entry_point_notifications.sh
-123
View File
@@ -1,123 +0,0 @@
name: Nightly builds
on:
schedule:
- cron: '14 4 * * *'
jobs:
matrix_prep:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from nightly_build_matrix_includes.json
- uses: actions/checkout@v2
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
build:
needs: matrix_prep
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-latest'
- name: Check out repository code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --all
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --all
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- uses: actions-rs/clippy-check@v1
name: Clippy checks
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: -- -D warnings
# COCONUT stuff
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
command: build
args: --all --features=coconut
- name: Run all tests with coconut enabled
uses: actions-rs/cargo@v1
with:
command: test
args: --all --features=coconut
- name: Run clippy with coconut enabled
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --features=coconut -- -D warnings
notification:
needs: build
runs-on: ubuntu-latest
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v2
- name: Keybase - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
NYM_PROJECT_NAME: "Nym nightly build"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
@@ -1,50 +0,0 @@
[
{
"os":"ubuntu-latest",
"rust":"stable",
"runOnEvent":"schedule"
},
{
"os":"windows-latest",
"rust":"stable",
"runOnEvent":"schedule"
},
{
"os":"macos-latest",
"rust":"stable",
"runOnEvent":"schedule"
},
{
"os":"ubuntu-latest",
"rust":"beta",
"runOnEvent":"schedule"
},
{
"os":"windows-latest",
"rust":"beta",
"runOnEvent":"schedule"
},
{
"os":"macos-latest",
"rust":"beta",
"runOnEvent":"schedule"
},
{
"os":"ubuntu-latest",
"rust":"nightly",
"runOnEvent":"schedule"
},
{
"os":"windows-latest",
"rust":"nightly",
"runOnEvent":"schedule"
},
{
"os":"macos-latest",
"rust":"nightly",
"runOnEvent":"schedule"
}
]
@@ -1,77 +0,0 @@
name: Publish Nym Wallet (MacOS)
on:
release:
types: [created]
defaults:
run:
working-directory: nym-wallet
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Check the release tag starts with `nym-wallet-`
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-wallet-...')
- name: Node v16
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install the Apple developer certificate for code signing
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$APPLE_CERTIFICATE" | base64 --decode --output $CERTIFICATE_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
- name: Install app dependencies and build it
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
run: yarn && yarn build
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
with:
files: nym-wallet/target/release/bundle/dmg/*.dmg
- name: Clean up keychain
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
@@ -1,46 +0,0 @@
name: Publish Nym Wallet (Ubuntu)
on:
release:
types: [created]
defaults:
run:
working-directory: nym-wallet
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Tauri dependencies
run: >
sudo apt-get update &&
sudo apt-get install -y webkit2gtk-4.0
- name: Check the release tag starts with `nym-wallet-`
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-wallet-...')
- name: Node v16
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install app dependencies and build it
run: yarn && yarn build
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
with:
files: nym-wallet/target/release/bundle/appimage/*.AppImage
+12
View File
@@ -0,0 +1,12 @@
name: Publish Nym Wallet
on:
push:
tags:
- nym-wallet-*
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Run a one-line script
run: echo Hello, world!
@@ -1,35 +0,0 @@
KEYBASE_NYM_CHANNEL=
KEYBASE_NYMBOT_USERNAME=
KEYBASE_NYMBOT_PAPERKEY=
NYM_NOTIFICATION_KIND=nightly
NYM_PROJECT_NAME=Nightly Build
#----------------------------------------------------------------
# Custom GitHub Actions mock env vars
IS_SUCCESS=true
#----------------------------------------------------------------
# GitHub Actions context mock env vars
GITHUB_SHA=abcdef
GITHUB_RUN_ID=123456
GITHUB_REPOSITORY=nymtech/nym
GITHUB_SERVER_URL=https://github.com
GIT_BRANCH_NAME=feature/testing-support-files
GIT_BRANCH=feature/testing-support-files
GIT_COMMIT_MESSAGE=This is the commit message
GITHUB_ACTOR=octocat
# add a Personal Access Token (PAT) generated from GitHub here for use in testing
GITHUB_TOKEN=
#----------------------------------------------------------------
# Network Explorer
NYM_CI_WWW_LOCATION=some-branch
NYM_CI_WWW_BASE=example.com
#----------------------------------------------------------------
# Nightly builds
WORKFLOW_CONCLUSION=success
SHOW_DEBUG=true
@@ -1,5 +0,0 @@
node_modules
.idea
# don't commit the lock file to avoid cross-platform issues
package-lock.json
-1
View File
@@ -1 +0,0 @@
16
-58
View File
@@ -1,58 +0,0 @@
# GitHub Actions Support Files
This is a collection of scripts and files to support GitHub Actions.
## Sending Notifications
These scripts send CI notifications to Keybase by creating messages from templates and env vars passed from GitHub Actions.
### Adding notifications to a GitHub Action
```
jobs:
build:
...
- name: Notifications - Node Install
run: npm install
working-directory: .github/workflows/support-files/notifications
- name: Notifications - Send
env:
NYM_NOTIFICATION_KIND: "my-component"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-network-explorer"
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
```
Notifications are run by adding the snippet above to a GitHub Action, and:
1. Installing node packages needed at run time
2. Set the env vars as required:
- `NYM_NOTIFICATION_KIND` matches the directory in `.github/workflows/support-files/${NYM_NOTIFICATION_KIND}` to provide the templates and extra scripting in `index.js`
- Keybase credentials, channel and other env vars for the status of the build and repo
3. Replacing the default entry point shell script on the `keybaseio/client:stable-node` docker image to run `.github/workflows/support-files/notifications/entry_point.sh`
### Running locally
You will need:
- Node 16 LTS
- npm
Copy `.github/workflows/support-files/.env.example` to `.github/workflows/support-files/.env` and valid Keybase credentials.
Then run `npm install` to get dependencies.
Start development mode for the notification type you want either by passing the value as an env var called `NYM_NOTIFICATION_KIND` or set the `.env` file values correctly.
```bash
cd .github/workflows/support-files
npm install
cp .env.example .env
vi .env
npm run dev
```
-1
View File
@@ -1 +0,0 @@
require('./notifications/send_message');
@@ -0,0 +1,2 @@
node_modules
.idea
@@ -4,14 +4,11 @@
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "node dev.js",
"format": "prettier --write **/*.js"
"format": "prettier --write send_message.js"
},
"dependencies": {
"dotenv": "^16.0.0",
"handlebars": "^4.7.7",
"keybase-bot": "^3.6.1",
"octokit": "^1.7.1"
"keybase-bot": "^3.6.1"
},
"devDependencies": {
"prettier": "2.3.2"
@@ -0,0 +1,69 @@
const Bot = require('keybase-bot');
const Handlebars = require('handlebars');
const fs = require('fs');
async function main() {
const data = { env: process.env };
// const data = { ...PASTE TEST DATA HERE ... }; // -- DEV: uncomment to set test data
// validation of environment
if(!(process.env.NYM_PROJECT_NAME || data.env.NYM_PROJECT_NAME)) {
throw new Error('Please set env var NYM_PROJECT_NAME with the project name for displaying in notification messages');
}
const keybaseChannel = process.env.KEYBASE_NYM_CHANNEL || data.env.KEYBASE_NYM_CHANNEL;
if(!keybaseChannel) {
throw new Error('Please set env var KEYBASE_NYM_CHANNEL with the channel name for the notification message');
}
// extract the git branch name
const GIT_BRANCH_NAME = (process.env.GITHUB_REF || data.env.GITHUB_REF).split('/').slice(2).join('/');
data.env.GIT_BRANCH_NAME = GIT_BRANCH_NAME;
const source = fs
.readFileSync(process.env.IS_SUCCESS === 'true' ? 'success' : 'failure')
.toString();
const template = Handlebars.compile(source);
const result = template(data);
// -- DEV: uncomment to show what is available in the handlebars template / show the result
// console.dir({ data }, { depth: null });
// console.log(result);
const bot = new Bot();
try {
const username = process.env.KEYBASE_NYMBOT_USERNAME;
const paperkey = process.env.KEYBASE_NYMBOT_PAPERKEY;
if(!username) {
throw new Error('Username is not defined. Please set env var KEYBASE_NYMBOT_USERNAME');
}
if(!paperkey) {
throw new Error('Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY');
}
console.log(`Initialising keybase with user "${username}" and key: "${'*'.repeat(paperkey.length)}"...`);
await bot.init(username, paperkey, { verbose: false });
const channel = {
name: 'nymtech_bot',
membersType: 'team',
topicName: keybaseChannel,
topic_type: 'CHAT',
};
const message = {
body: result,
};
console.log(`Sending to ${channel.name}#${channel.topicName}...`);
await bot.chat.send(channel, message);
console.log('Message sent!');
} catch (error) {
console.error(error);
process.exitCode = -1;
} finally {
await bot.deinit();
}
}
main();
@@ -5,7 +5,7 @@
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
Commit message:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
@@ -1,29 +0,0 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
async function addToContextAndValidate(context) {
if (!context.env.NYM_CI_WWW_LOCATION) {
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
}
if (!context.env.NYM_CI_WWW_BASE) {
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
}
}
async function getMessageBody(context) {
const source = fs
.readFileSync(
context.env.IS_SUCCESS === 'true'
? path.resolve(__dirname, 'templates', 'success')
: path.resolve(__dirname, 'templates', 'failure'),
)
.toString();
const template = Handlebars.compile(source);
return template(context);
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
@@ -1,162 +0,0 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
const { Octokit, App } = require('octokit');
async function addToContextAndValidate(context) {
if (!context.env.WORKFLOW_CONCLUSION) {
throw new Error('Please ensure the env var WORKFLOW_CONCLUSION is set');
}
if (!context.env.GITHUB_TOKEN) {
throw new Error('Please ensure the env var GITHUB_TOKEN is set');
}
if (!context.env.GITHUB_RUN_ID) {
throw new Error('Please ensure the env var GITHUB_RUN_ID is set');
}
if (!context.env.GITHUB_REPOSITORY) {
throw new Error('Please ensure the env var GITHUB_REPOSITORY is set');
}
}
async function getMessageBody(context) {
const source = fs
.readFileSync(
context.env.WORKFLOW_CONCLUSION === 'success'
? path.resolve(__dirname, 'templates', 'success')
: path.resolve(__dirname, 'templates', 'failure'),
)
.toString();
const template = Handlebars.compile(source);
// get job details from GitHub API
const octokit = new Octokit({ auth: context.env.GITHUB_TOKEN });
const [owner, repo] = context.env.GITHUB_REPOSITORY.split('/');
const {
data: { jobs },
} = await octokit.rest.actions.listJobsForWorkflowRun({
run_id: context.env.GITHUB_RUN_ID,
owner,
repo,
});
// uncomment this to see what is available for each job
if(process.env.SHOW_DEBUG) {
console.dir(jobs, { depth: null });
}
/*
a sample of the response is:
{
total_count: 10,
jobs: [
{
id: 5182940024,
run_id: 1840752095,
run_url: 'https://api.github.com/repos/nymtech/nym/actions/runs/1840752095',
run_attempt: 1,
node_id: 'CR_kwDODdjOis8AAAABNO1jeA',
head_sha: 'aa00eb70d57751bfa556bd3602df87c7473367fc',
url: 'https://api.github.com/repos/nymtech/nym/actions/jobs/5182940024',
html_url: 'https://github.com/nymtech/nym/runs/5182940024?check_suite_focus=true',
status: 'completed',
conclusion: 'success',
started_at: '2022-02-14T11:28:34Z',
completed_at: '2022-02-14T11:28:38Z',
name: 'matrix_prep',
steps: [
{
name: 'Set up job',
status: 'completed',
conclusion: 'success',
number: 1,
started_at: '2022-02-14T13:28:34.000+02:00',
completed_at: '2022-02-14T13:28:36.000+02:00'
},
{
name: 'Run actions/checkout@v2',
status: 'completed',
conclusion: 'success',
number: 2,
started_at: '2022-02-14T13:28:36.000+02:00',
completed_at: '2022-02-14T13:28:37.000+02:00'
},
...
],
check_run_url: 'https://api.github.com/repos/nymtech/nym/check-runs/5182940024',
labels: [ 'ubuntu-latest' ],
runner_id: 1,
runner_name: 'Hosted Agent',
runner_group_id: 2,
runner_group_name: 'GitHub Actions'
},
{
id: 5182943473,
run_id: 1840752095,
run_url: 'https://api.github.com/repos/nymtech/nym/actions/runs/1840752095',
run_attempt: 1,
node_id: 'CR_kwDODdjOis8AAAABNO1w8Q',
head_sha: 'aa00eb70d57751bfa556bd3602df87c7473367fc',
url: 'https://api.github.com/repos/nymtech/nym/actions/jobs/5182943473',
html_url: 'https://github.com/nymtech/nym/runs/5182943473?check_suite_focus=true',
status: 'completed',
conclusion: 'failure',
started_at: '2022-02-14T11:29:04Z',
completed_at: '2022-02-14T11:55:45Z',
name: 'build (macos-latest, stable, schedule)',
steps: [
{
name: 'Set up job',
status: 'completed',
conclusion: 'success',
number: 1,
started_at: '2022-02-14T13:29:04.000+02:00',
completed_at: '2022-02-14T13:29:26.000+02:00'
},
{
name: 'Install Dependencies (Linux)',
status: 'completed',
conclusion: 'skipped',
number: 2,
started_at: '2022-02-14T13:29:26.000+02:00',
completed_at: '2022-02-14T13:29:26.000+02:00'
},
{
name: 'Keybase - Send Notification',
status: 'completed',
conclusion: 'failure',
number: 15,
started_at: '2022-02-14T13:55:44.000+02:00',
completed_at: '2022-02-14T13:55:44.000+02:00'
},
],
check_run_url: 'https://api.github.com/repos/nymtech/nym/check-runs/5182943473',
labels: [ 'macos-latest' ],
runner_id: 4,
runner_name: 'GitHub Actions 4',
runner_group_id: 2,
runner_group_name: 'GitHub Actions'
},
...
]
}
*/
const jobResults = jobs
.map((job) => {
const icon = job.conclusion === 'success' ? '🟩' : '🟥';
// each job is converted into formatted markdown text
return `${icon} ${job.conclusion}: ${job.name} - ${job.html_url}`;
})
// and join with newlines for display in the template
.join('\n');
return template({ ...context, jobResults });
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
@@ -1,9 +0,0 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :rocket: {{ env.NYM_PROJECT_NAME }}
> 🔴 **FAILURE** :cry:
> `when` {{ timestamp }}
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
{{ jobResults }}
@@ -1,9 +0,0 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }}
> ✅ **SUCCESS**
> `when` {{ timestamp }}
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
{{ jobResults }}
@@ -1,153 +0,0 @@
require('dotenv').config();
const Bot = require('keybase-bot');
let context = {
kinds: ['network-explorer', 'nightly'],
};
/**
* Validate that all required env and context vars are available
*/
function validateContext() {
if (!context.env.NYM_NOTIFICATION_KIND) {
throw new Error(
'Please set env var NYM_NOTIFICATION_KIND with the project kind that matches a directory in ".github/workflows/support-files"',
);
}
if (!context.kinds.includes(context.env.NYM_NOTIFICATION_KIND)) {
throw new Error(`Env var NYM_NOTIFICATION_KIND is not in ${context.kinds}`);
}
if (!context.env.NYM_PROJECT_NAME) {
throw new Error(
'Please set env var NYM_PROJECT_NAME with the project name for displaying in notification messages',
);
}
if (!context.env.KEYBASE_NYM_CHANNEL) {
throw new Error(
'Please set env var KEYBASE_NYM_CHANNEL with the channel name for the notification message',
);
}
if (!context.env.KEYBASE_NYMBOT_USERNAME) {
throw new Error(
'Username is not defined. Please set env var KEYBASE_NYMBOT_USERNAME',
);
}
if (!context.env.KEYBASE_NYMBOT_PAPERKEY) {
throw new Error(
'Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY',
);
}
}
/**
* Creates a context that will be available in the templates for rendering notifications
*/
function createTemplateContext() {
const options = { dateStyle: 'full', timeStyle: 'long' };
context.timestamp = new Date().toLocaleString(undefined, options);
// add environment to template context and validate
context.env = process.env;
try {
validateContext();
} catch (e) {
if(process.env.SHOW_DEBUG) {
// recursively print the context for easy debugging and rethrow the error
console.dir({ context }, { depth: null });
}
throw e;
}
context.kind = context.env.NYM_NOTIFICATION_KIND;
context.keybase = {
channel: context.env.KEYBASE_NYM_CHANNEL,
username: context.env.KEYBASE_NYMBOT_USERNAME,
paperkey: context.env.KEYBASE_NYMBOT_PAPERKEY,
};
if (!context.env.GIT_BRANCH_NAME) {
context.env.GIT_BRANCH_NAME = context.env.GITHUB_REF.split('/')
.slice(2)
.join('/');
}
context.status = process.env.IS_SUCCESS === 'true' ? 'success' : 'failure';
}
async function sendKeybaseMessage(messageBody) {
const bot = new Bot();
try {
console.log(
`Initialising keybase with user "${
context.keybase.username
}" and key: "${'*'.repeat(context.keybase.paperkey.length)}"...`,
);
await bot.init(context.keybase.username, context.keybase.paperkey, {
verbose: false,
});
const channel = {
name: 'nymtech_bot',
membersType: 'team',
topicName: context.keybase.channel,
topic_type: 'CHAT',
};
const message = {
body: messageBody,
};
console.log(`Sending to ${channel.name}#${channel.topicName}...`);
await bot.chat.send(channel, message);
console.log('Message sent!');
} catch (error) {
console.error(error);
process.exitCode = -1;
} finally {
await bot.deinit();
}
}
/**
* Uses the `kind` set in the context to process the context and generate a notification message
* @returns {Promise<string>} A string notification message body
*/
async function processKindScript() {
const script = require(`../${context.kind}`);
if (!script.addToContextAndValidate) {
throw new Error(
`"./${context.kind}/index.js" does not export a method called "async addToContextAndValidate(context)"`,
);
}
if (!script.getMessageBody) {
throw new Error(
`"./${context.kind}/index.js" does not export a method called "async getMessageBody(context)"`,
);
}
// call the script to modify and validate the context
await script.addToContextAndValidate(context);
// let the script create a message body and return the result as a string for sending
return await script.getMessageBody(context);
}
/**
* The main function, as async so that await syntax is available
*/
async function main() {
createTemplateContext();
console.log(`Sending notification for kind "${context.kind}"...`);
const messageBody = await processKindScript();
if(process.env.SHOW_DEBUG) {
console.log('-----------------------------------------');
console.log(messageBody);
console.log('-----------------------------------------');
}
await sendKeybaseMessage(messageBody);
}
// call main function and let NodeJS handle the promise
main();
-29
View File
@@ -1,29 +0,0 @@
name: Test CI
on: workflow_dispatch
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
- name: Check out repository code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v1
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --all
+15 -12
View File
@@ -19,27 +19,30 @@ jobs:
override: true
components: rustfmt, clippy
- uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
# token credentials (non-coconut) don't work for wasm right now
# - uses: actions-rs/cargo@v1
# with:
# command: build
# args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
- uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown --features=coconut
- uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path clients/webassembly/Cargo.toml
# for some reason this does not seem to work correctly, leave it for later, building is good enough for now
# - uses: actions-rs/cargo@v1
# with:
# command: test
# args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path clients/webassembly/Cargo.toml -- --check
- uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown -- -D warnings
# for some reason this does not seem to work correctly, leave it for later, building is good enough for now
# - uses: actions-rs/cargo@v1
# with:
# command: clippy
# args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown -- -D warnings
Generated
+121 -391
View File
@@ -68,9 +68,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.53"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
[[package]]
name = "app"
@@ -638,41 +638,11 @@ dependencies = [
"atty",
"bitflags",
"strsim 0.8.0",
"textwrap 0.11.0",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "clap"
version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a30c3bf9ff12dfe5dae53f0a96e0febcd18420d1c0e7fad77796d9d5c4b5375"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"indexmap",
"lazy_static",
"os_str_bytes",
"strsim 0.10.0",
"termcolor",
"textwrap 0.14.2",
]
[[package]]
name = "clap_derive"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "517358c28fcef6607bf6f76108e02afad7e82297d132a6b846dcc1fc3efcd153"
dependencies = [
"heck 0.4.0",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "client-core"
version = "0.12.0"
@@ -802,38 +772,13 @@ dependencies = [
]
[[package]]
name = "console-api"
version = "0.1.1"
name = "console_error_panic_hook"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14f67643a7d716307ad10b3e3aef02826382acbe349a3e7605ac57556148bc87"
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
dependencies = [
"prost",
"prost-types",
"tonic",
"tonic-build",
"tracing-core",
]
[[package]]
name = "console-subscriber"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829835c211a0247cd11e65e13cec8696b879374879c35ce162ce8098b23c90d4"
dependencies = [
"console-api",
"crossbeam-channel",
"futures",
"hdrhistogram",
"humantime 2.1.0",
"serde",
"serde_json",
"thread_local",
"tokio",
"tokio-stream",
"tonic",
"tracing",
"tracing-core",
"tracing-subscriber",
"cfg-if 0.1.10",
"wasm-bindgen",
]
[[package]]
@@ -1002,9 +947,9 @@ dependencies = [
[[package]]
name = "cosmwasm-crypto"
version = "1.0.0-beta4"
version = "1.0.0-beta3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f903ebbabc0d4880dbc76148efb8be8fc29fa4bf294c440c3d70da1c8bcafff7"
checksum = "a380b87642204557629c9b72988c47b55fbfe6d474960adba56b22331504956a"
dependencies = [
"digest 0.9.0",
"ed25519-zebra",
@@ -1015,18 +960,18 @@ dependencies = [
[[package]]
name = "cosmwasm-derive"
version = "1.0.0-beta4"
version = "1.0.0-beta3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "832bebef577ecb394603de8e2bf0de429b74aa364e17dec18e15ce37e71b0cae"
checksum = "866713b2fe13f23038c7d8824c3059d1f28dd94685fb406d1533c4eeeefeefae"
dependencies = [
"syn",
]
[[package]]
name = "cosmwasm-std"
version = "1.0.0-beta4"
version = "1.0.0-beta3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6238c45840cc9de5a39f0f619e3a4f7c38c5d2c6ac9e3e4d72751ee045e6d7da"
checksum = "8dbb9939b31441dfa9af3ec9740c8a24d585688401eff1b6b386abb7ad0d10a8"
dependencies = [
"base64",
"cosmwasm-crypto",
@@ -1091,7 +1036,7 @@ checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
dependencies = [
"atty",
"cast",
"clap 2.33.3",
"clap",
"criterion-plot",
"csv",
"itertools",
@@ -1253,7 +1198,7 @@ checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a"
dependencies = [
"cssparser-macros",
"dtoa-short",
"itoa 0.4.8",
"itoa",
"matches",
"phf 0.8.0",
"proc-macro2",
@@ -1280,7 +1225,7 @@ checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr",
"csv-core",
"itoa 0.4.8",
"itoa",
"ryu",
"serde",
]
@@ -1996,12 +1941,6 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "fixedbitset"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e"
[[package]]
name = "flate2"
version = "1.0.22"
@@ -2218,10 +2157,6 @@ name = "futures-timer"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
dependencies = [
"gloo-timers",
"send_wrapper",
]
[[package]]
name = "futures-util"
@@ -2268,7 +2203,6 @@ dependencies = [
"log",
"network-defaults",
"nymsphinx",
"pemstore",
"rand 0.7.3",
"secp256k1",
"thiserror",
@@ -2512,7 +2446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518"
dependencies = [
"anyhow",
"heck 0.3.3",
"heck",
"proc-macro-crate 1.1.0",
"proc-macro-error",
"proc-macro2",
@@ -2559,19 +2493,6 @@ dependencies = [
"regex",
]
[[package]]
name = "gloo-timers"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f16c88aa13d2656ef20d1c042086b8767bbe2bdb62526894275a1b062161b2e"
dependencies = [
"futures-channel",
"futures-core",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "gobject-sys"
version = "0.10.0"
@@ -2665,7 +2586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79"
dependencies = [
"anyhow",
"heck 0.3.3",
"heck",
"proc-macro-crate 1.1.0",
"proc-macro-error",
"proc-macro2",
@@ -2675,9 +2596,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.3.10"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c9de88456263e249e241fcd211d3954e2c9b0ef7ccfc235a444eb367cae3689"
checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472"
dependencies = [
"bytes",
"fnv",
@@ -2730,19 +2651,6 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "hdrhistogram"
version = "7.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6490be71f07a5f62b564bc58e36953f675833df11c7e4a0647bee7a07ca1ec5e"
dependencies = [
"base64",
"byteorder",
"flate2",
"nom",
"num-traits",
]
[[package]]
name = "headers"
version = "0.3.4"
@@ -2777,12 +2685,6 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.1.19"
@@ -2846,14 +2748,14 @@ checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
dependencies = [
"bytes",
"fnv",
"itoa 0.4.8",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.4"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5"
dependencies = [
"bytes",
"http",
@@ -2905,9 +2807,9 @@ dependencies = [
[[package]]
name = "hyper"
version = "0.14.16"
version = "0.14.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55"
checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593"
dependencies = [
"bytes",
"futures-channel",
@@ -2918,7 +2820,7 @@ dependencies = [
"http-body",
"httparse",
"httpdate",
"itoa 0.4.8",
"itoa",
"pin-project-lite",
"socket2",
"tokio",
@@ -2963,18 +2865,6 @@ dependencies = [
"webpki-roots",
]
[[package]]
name = "hyper-timeout"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
@@ -3186,12 +3076,6 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "javascriptcore-rs"
version = "0.14.0"
@@ -3314,9 +3198,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.113"
version = "0.2.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
[[package]]
name = "libgit2-sys"
@@ -3464,6 +3348,12 @@ dependencies = [
"autocfg 1.0.1",
]
[[package]]
name = "memory_units"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
[[package]]
name = "mime"
version = "0.3.16"
@@ -3542,7 +3432,6 @@ dependencies = [
"serde",
"serde_repr",
"thiserror",
"time 0.3.6",
"ts-rs",
]
@@ -3592,12 +3481,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "multimap"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]]
name = "native-tls"
version = "0.2.8"
@@ -3669,6 +3552,7 @@ dependencies = [
"cfg-if 1.0.0",
"hex-literal",
"serde",
"time 0.3.3",
"url",
]
@@ -3799,20 +3683,11 @@ dependencies = [
"syn",
]
[[package]]
name = "num_threads"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71a1eb3a36534514077c1e079ada2fb170ef30c47d203aa6916138cf882ecd52"
dependencies = [
"libc",
]
[[package]]
name = "nym-client"
version = "0.12.1"
dependencies = [
"clap 2.33.3",
"clap",
"client-core",
"coconut-interface",
"config",
@@ -3842,15 +3717,38 @@ dependencies = [
"websocket-requests",
]
[[package]]
name = "nym-client-wasm"
version = "0.12.0"
dependencies = [
"coconut-interface",
"console_error_panic_hook",
"credentials",
"crypto",
"futures",
"gateway-client",
"js-sys",
"nymsphinx",
"rand 0.7.3",
"serde",
"topology",
"url",
"validator-client",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test",
"wasm-utils",
"wee_alloc",
]
[[package]]
name = "nym-gateway"
version = "0.12.1"
dependencies = [
"anyhow",
"bandwidth-claim-contract",
"bip39",
"bs58",
"clap 3.0.10",
"clap",
"coconut-interface",
"colored",
"config",
@@ -3868,7 +3766,6 @@ dependencies = [
"mixnode-common",
"network-defaults",
"nymsphinx",
"once_cell",
"pemstore",
"pretty_env_logger",
"rand 0.7.3",
@@ -3891,9 +3788,8 @@ dependencies = [
name = "nym-mixnode"
version = "0.12.1"
dependencies = [
"anyhow",
"bs58",
"clap 3.0.10",
"clap",
"colored",
"config",
"crypto",
@@ -3901,14 +3797,11 @@ dependencies = [
"dotenv",
"futures",
"humantime-serde",
"lazy_static",
"log",
"mixnet-client",
"mixnode-common",
"nonexhaustive-delayqueue",
"nymsphinx",
"nymsphinx-params",
"nymsphinx-types",
"pemstore",
"pretty_env_logger",
"rand 0.7.3",
@@ -3929,7 +3822,7 @@ dependencies = [
name = "nym-network-requester"
version = "0.12.0"
dependencies = [
"clap 2.33.3",
"clap",
"dirs",
"futures",
"ipnetwork",
@@ -3950,7 +3843,7 @@ dependencies = [
name = "nym-socks5-client"
version = "0.12.1"
dependencies = [
"clap 2.33.3",
"clap",
"client-core",
"coconut-interface",
"config",
@@ -3987,11 +3880,9 @@ version = "0.12.0"
dependencies = [
"anyhow",
"attohttpc 0.18.0",
"cfg-if 1.0.0",
"clap 2.33.3",
"clap",
"coconut-interface",
"config",
"console-subscriber",
"credentials",
"crypto",
"dirs",
@@ -4007,6 +3898,7 @@ dependencies = [
"pretty_env_logger",
"rand 0.7.3",
"rand 0.8.4",
"rand_chacha 0.3.1",
"reqwest",
"rocket",
"rocket_cors",
@@ -4015,7 +3907,7 @@ dependencies = [
"serde_json",
"sqlx",
"thiserror",
"time 0.3.6",
"time 0.3.3",
"tokio",
"topology",
"url",
@@ -4269,15 +4161,6 @@ dependencies = [
"log",
]
[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr",
]
[[package]]
name = "owning_ref"
version = "0.4.1"
@@ -4510,16 +4393,6 @@ dependencies = [
"sha-1 0.8.2",
]
[[package]]
name = "petgraph"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "phf"
version = "0.8.0"
@@ -4862,26 +4735,6 @@ dependencies = [
"prost-derive",
]
[[package]]
name = "prost-build"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5"
dependencies = [
"bytes",
"heck 0.3.3",
"itertools",
"lazy_static",
"log",
"multimap",
"petgraph",
"prost",
"prost-types",
"regex",
"tempfile",
"which",
]
[[package]]
name = "prost-derive"
version = "0.9.0"
@@ -5805,12 +5658,6 @@ dependencies = [
"pest",
]
[[package]]
name = "send_wrapper"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0"
[[package]]
name = "serde"
version = "1.0.130"
@@ -5822,9 +5669,9 @@ dependencies = [
[[package]]
name = "serde-json-wasm"
version = "0.3.2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "042ac496d97e5885149d34139bad1d617192770d7eb8f1866da2317ff4501853"
checksum = "50eef3672ec8fa45f3457fd423ba131117786784a895548021976117c1ded449"
dependencies = [
"serde",
]
@@ -5876,7 +5723,7 @@ version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
dependencies = [
"itoa 0.4.8",
"itoa",
"ryu",
"serde",
]
@@ -5899,7 +5746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
dependencies = [
"dtoa",
"itoa 0.4.8",
"itoa",
"serde",
"url",
]
@@ -5911,7 +5758,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
dependencies = [
"form_urlencoded",
"itoa 0.4.8",
"itoa",
"ryu",
"serde",
]
@@ -6004,15 +5851,6 @@ dependencies = [
"opaque-debug 0.3.0",
]
[[package]]
name = "sharded-slab"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
dependencies = [
"lazy_static",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
@@ -6241,7 +6079,7 @@ dependencies = [
"futures-util",
"hashlink",
"hex",
"itoa 0.4.8",
"itoa",
"libc",
"libsqlite3-sys",
"log",
@@ -6272,7 +6110,7 @@ dependencies = [
"dotenv",
"either",
"futures",
"heck 0.3.3",
"heck",
"once_cell",
"proc-macro2",
"quote",
@@ -6466,7 +6304,7 @@ version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
dependencies = [
"heck 0.3.3",
"heck",
"proc-macro2",
"quote",
"syn",
@@ -6478,7 +6316,7 @@ version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
dependencies = [
"heck 0.3.3",
"heck",
"proc-macro2",
"quote",
"syn",
@@ -6672,7 +6510,7 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
dependencies = [
"heck 0.3.3",
"heck",
"pkg-config",
"strum 0.18.0",
"strum_macros 0.18.0",
@@ -6689,7 +6527,7 @@ checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6"
dependencies = [
"anyhow",
"cfg-expr",
"heck 0.3.3",
"heck",
"itertools",
"pkg-config",
"strum 0.21.0",
@@ -6936,7 +6774,7 @@ dependencies = [
"subtle 2.4.1",
"subtle-encoding",
"tendermint-proto",
"time 0.3.6",
"time 0.3.3",
"zeroize",
]
@@ -6969,7 +6807,7 @@ dependencies = [
"serde",
"serde_bytes",
"subtle-encoding",
"time 0.3.6",
"time 0.3.3",
]
[[package]]
@@ -6997,7 +6835,7 @@ dependencies = [
"tendermint-config",
"tendermint-proto",
"thiserror",
"time 0.3.6",
"time 0.3.3",
"tokio",
"tracing",
"url",
@@ -7034,12 +6872,6 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "textwrap"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
[[package]]
name = "thin-slice"
version = "0.1.1"
@@ -7103,13 +6935,12 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.6"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d54b9298e05179c335de2b9645d061255bcd5155f843b3e328d2cfe0a5b413"
checksum = "cde1cf55178e0293453ba2cca0d5f8392a922e52aa958aee9c28ed02becc6d03"
dependencies = [
"itoa 1.0.1",
"itoa",
"libc",
"num_threads",
"serde",
"time-macros 0.2.3",
]
@@ -7164,10 +6995,11 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.15.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838"
checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc"
dependencies = [
"autocfg 1.0.1",
"bytes",
"libc",
"memchr",
@@ -7178,25 +7010,14 @@ dependencies = [
"pin-project-lite",
"signal-hook-registry",
"tokio-macros",
"tracing",
"winapi",
]
[[package]]
name = "tokio-io-timeout"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
dependencies = [
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-macros"
version = "1.7.0"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
@@ -7286,49 +7107,6 @@ dependencies = [
"serde",
]
[[package]]
name = "tonic"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff08f4649d10a70ffa3522ca559031285d8e421d727ac85c60825761818f5d0a"
dependencies = [
"async-stream",
"async-trait",
"base64",
"bytes",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"hyper-timeout",
"percent-encoding",
"pin-project",
"prost",
"prost-derive",
"tokio",
"tokio-stream",
"tokio-util",
"tower",
"tower-layer",
"tower-service",
"tracing",
"tracing-futures",
]
[[package]]
name = "tonic-build"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757"
dependencies = [
"proc-macro2",
"prost-build",
"quote",
"syn",
]
[[package]]
name = "topology"
version = "0.1.0"
@@ -7343,33 +7121,6 @@ dependencies = [
"version-checker",
]
[[package]]
name = "tower"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5651b5f6860a99bd1adb59dbfe1db8beb433e73709d9032b413a77e2fb7c066a"
dependencies = [
"futures-core",
"futures-util",
"indexmap",
"pin-project",
"pin-project-lite",
"rand 0.8.4",
"slab",
"tokio",
"tokio-stream",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
[[package]]
name = "tower-service"
version = "0.3.1"
@@ -7383,23 +7134,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8"
dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.20"
@@ -7409,27 +7147,6 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "tracing-futures"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
dependencies = [
"pin-project",
"tracing",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77be66445c4eeebb934a7340f227bfe7b338173d3f8c00a60a5a58005c9faecf"
dependencies = [
"sharded-slab",
"thread_local",
"tracing-core",
]
[[package]]
name = "try-lock"
version = "0.2.3"
@@ -7663,7 +7380,6 @@ dependencies = [
"url",
"validator-api-requests",
"vesting-contract",
"vesting-contract-common",
]
[[package]]
@@ -7738,13 +7454,7 @@ dependencies = [
name = "vesting-contract-common"
version = "0.1.0"
dependencies = [
"config",
"cosmwasm-std",
"cw-storage-plus",
"mixnet-contract-common",
"schemars",
"serde",
"ts-rs",
]
[[package]]
@@ -7854,6 +7564,30 @@ version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
[[package]]
name = "wasm-bindgen-test"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96f1aa7971fdf61ef0f353602102dbea75a56e225ed036c1e3740564b91e6b7e"
dependencies = [
"console_error_panic_hook",
"js-sys",
"scoped-tls",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test-macro",
]
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6006f79628dfeb96a86d4db51fbf1344cd7fd8408f06fc9aa3c84913a4789688"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "wasm-utils"
version = "0.1.0"
@@ -7890,15 +7624,12 @@ dependencies = [
"ethereum-types",
"futures",
"futures-timer",
"getrandom 0.2.3",
"headers",
"hex",
"js-sys",
"jsonrpc-core",
"log",
"parking_lot",
"pin-project",
"rand 0.8.4",
"reqwest",
"rlp",
"secp256k1",
@@ -7910,8 +7641,6 @@ dependencies = [
"tokio-stream",
"tokio-util",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web3-async-native-tls",
]
@@ -8025,14 +7754,15 @@ dependencies = [
]
[[package]]
name = "which"
version = "4.2.2"
name = "wee_alloc"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9"
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
dependencies = [
"either",
"lazy_static",
"cfg-if 0.1.10",
"libc",
"memory_units",
"winapi",
]
[[package]]
@@ -8247,4 +7977,4 @@ checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33"
dependencies = [
"cc",
"libc",
]
]
+3 -2
View File
@@ -11,13 +11,13 @@ panic = "abort"
[workspace]
resolver = "2"
members = [
"clients/client-core",
"clients/native",
"clients/native/websocket-requests",
"clients/socks5",
"clients/tauri-client/src-tauri",
"clients/webassembly",
"common/client-libs/gateway-client",
"common/client-libs/mixnet-client",
"common/client-libs/validator-client",
@@ -60,6 +60,7 @@ members = [
default-members = [
"clients/native",
"clients/socks5",
# "clients/webassembly",
"gateway",
"service-providers/network-requester",
"mixnode",
@@ -67,4 +68,4 @@ default-members = [
"explorer-api",
]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly"]
exclude = ["explorer", "contracts", "tokenomics-py"]
+3 -13
View File
@@ -1,9 +1,8 @@
test: build clippy-all cargo-test wasm fmt
happy: fmt clippy-happy test
all: clippy-all test fmt
happy: clippy-happy test fmt
clippy-all: clippy-all-main clippy-all-contracts clippy-all-wallet
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet
cargo-test: test-main test-contracts test-wallet
build: build-main build-contracts build-wallet
test: test-main test-contracts test-wallet
fmt: fmt-main fmt-contracts fmt-wallet
clippy-happy-main:
@@ -33,15 +32,6 @@ test-contracts:
test-wallet:
cargo test --manifest-path nym-wallet/Cargo.toml --all-features
build-main:
cargo build
build-contracts:
cargo build --manifest-path contracts/Cargo.toml
build-wallet:
cargo build --manifest-path nym-wallet/Cargo.toml
fmt-main:
cargo fmt --all
+1 -1
View File
@@ -2,7 +2,7 @@
name = "client-core"
version = "0.12.0"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+14 -30
View File
@@ -121,16 +121,12 @@ impl<T: NymConfig> Config<T> {
self.client.testnet_mode = testnet_mode;
}
pub fn with_gateway_endpoint<S: Into<String>>(&mut self, id: S, owner: S, listener: S) {
self.client.gateway_endpoint = GatewayEndpoint {
gateway_id: id.into(),
gateway_owner: owner.into(),
gateway_listener: listener.into(),
};
pub fn with_gateway_id<S: Into<String>>(&mut self, id: S) {
self.client.gateway_id = id.into();
}
pub fn with_gateway_id<S: Into<String>>(&mut self, id: S) {
self.client.gateway_endpoint.gateway_id = id.into();
pub fn with_gateway_listener<S: Into<String>>(&mut self, gateway_listener: S) {
self.client.gateway_listener = gateway_listener.into();
}
#[cfg(not(feature = "coconut"))]
@@ -202,15 +198,11 @@ impl<T: NymConfig> Config<T> {
}
pub fn get_gateway_id(&self) -> String {
self.client.gateway_endpoint.gateway_id.clone()
}
pub fn get_gateway_owner(&self) -> String {
self.client.gateway_endpoint.gateway_owner.clone()
self.client.gateway_id.clone()
}
pub fn get_gateway_listener(&self) -> String {
self.client.gateway_endpoint.gateway_listener.clone()
self.client.gateway_listener.clone()
}
#[cfg(not(feature = "coconut"))]
@@ -280,19 +272,6 @@ impl<T: NymConfig> Default for Config<T> {
}
}
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
struct GatewayEndpoint {
/// gateway_id specifies ID of the gateway to which the client should send messages.
/// If initially omitted, a random gateway will be chosen from the available topology.
gateway_id: String,
/// Address of the gateway owner to which the client should send messages.
gateway_owner: String,
/// Address of the gateway listener to which all client requests should be sent.
gateway_listener: String,
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Client<T> {
/// Version of the client for which this configuration was created.
@@ -334,8 +313,12 @@ pub struct Client<T> {
/// sent but not received back.
reply_encryption_key_store_path: PathBuf,
/// Information regarding how the client should send data to gateway.
gateway_endpoint: GatewayEndpoint,
/// gateway_id specifies ID of the gateway to which the client should send messages.
/// If initially omitted, a random gateway will be chosen from the available topology.
gateway_id: String,
/// Address of the gateway listener to which all client requests should be sent.
gateway_listener: String,
/// Path to directory containing public/private keys used for bandwidth token purchase.
/// Those are saved in case of emergency, to be able to reclaim bandwidth tokens.
@@ -374,7 +357,8 @@ impl<T: NymConfig> Default for Client<T> {
gateway_shared_key_file: Default::default(),
ack_key_file: Default::default(),
reply_encryption_key_store_path: Default::default(),
gateway_endpoint: Default::default(),
gateway_id: "".to_string(),
gateway_listener: "".to_string(),
#[cfg(not(feature = "coconut"))]
backup_bandwidth_token_keys_dir: Default::default(),
#[cfg(not(feature = "coconut"))]
+1 -1
View File
@@ -2,7 +2,7 @@
name = "nym-client"
version = "0.12.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
rust-version = "1.56"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -2441,9 +2441,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true,
"funding": [
{
@@ -3806,9 +3806,9 @@
"optional": true
},
"node_modules/nanoid": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
"version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
"dev": true,
"peer": true,
"bin": {
@@ -3943,9 +3943,9 @@
}
},
"node_modules/nth-check": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
"integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
"dependencies": {
"boolbase": "^1.0.0"
},
@@ -6085,9 +6085,9 @@
}
},
"node_modules/url-parse": {
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"dependencies": {
"querystringify": "^2.1.1",
@@ -8853,9 +8853,9 @@
}
},
"follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true
},
"for-in": {
@@ -9871,9 +9871,9 @@
"optional": true
},
"nanoid": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
"version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
"dev": true,
"peer": true
},
@@ -9984,9 +9984,9 @@
}
},
"nth-check": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz",
"integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==",
"requires": {
"boolbase": "^1.0.0"
}
@@ -11733,9 +11733,9 @@
}
},
"url-parse": {
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",
+6 -11
View File
@@ -59,6 +59,12 @@ eth_endpoint = '{{ client.eth_endpoint }}'
##### additional client config options #####
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_id }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_listener }}'
# A gateway specific, optional, base58 stringified shared key used for
# communication with particular gateway.
gateway_shared_key_file = '{{ client.gateway_shared_key_file }}'
@@ -72,17 +78,6 @@ ack_key_file = '{{ client.ack_key_file }}'
# Absolute path to the home Nym Clients directory.
nym_root_directory = '{{ client.nym_root_directory }}'
[client.gateway_endpoint]
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_endpoint.gateway_id }}'
# Address of the gateway owner to which the client should send messages.
gateway_owner = '{{ client.gateway_endpoint.gateway_owner }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_endpoint.gateway_listener }}'
##### socket config options #####
-5
View File
@@ -160,10 +160,6 @@ impl NymClient {
if gateway_id.is_empty() {
panic!("The identity of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_owner = self.config.get_base().get_gateway_owner();
if gateway_owner.is_empty() {
panic!("The owner of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_address = self.config.get_base().get_gateway_listener();
if gateway_address.is_empty() {
panic!("The address of the gateway is unknown - did you run `nym-client` init?")
@@ -189,7 +185,6 @@ impl NymClient {
gateway_address,
self.key_manager.identity_keypair(),
gateway_identity,
gateway_owner,
Some(self.key_manager.gateway_shared_key()),
mixnet_message_sender,
ack_sender,
+6 -6
View File
@@ -136,7 +136,6 @@ async fn register_with_gateway(
let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(),
gateway.identity_key,
gateway.owner.clone(),
our_identity.clone(),
timeout,
);
@@ -256,14 +255,15 @@ pub async fn execute(matches: ArgMatches<'static>) {
chosen_gateway_id,
)
.await;
config
.get_base_mut()
.with_gateway_id(gateway_details.identity_key.to_base58_string());
let shared_keys =
register_with_gateway(&gateway_details, key_manager.identity_keypair()).await;
config.get_base_mut().with_gateway_endpoint(
gateway_details.identity_key.to_base58_string(),
gateway_details.owner.clone(),
gateway_details.clients_address(),
);
config
.get_base_mut()
.with_gateway_listener(gateway_details.clients_address());
key_manager.insert_gateway_shared_key(shared_keys);
let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base());
+3 -3
View File
@@ -32,7 +32,7 @@ fn parse_validators(raw: &str) -> Vec<Url> {
.collect()
}
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> Config {
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if let Some(raw_validators) = matches.value_of("validators") {
config
.get_base_mut()
@@ -58,7 +58,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_endpoint) = matches.value_of(ETH_ENDPOINT_ARG_NAME) {
config.get_base_mut().with_eth_endpoint(eth_endpoint);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_endpoint(DEFAULT_ETH_ENDPOINT);
@@ -66,7 +66,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_private_key) = matches.value_of(ETH_PRIVATE_KEY_ARG_NAME) {
config.get_base_mut().with_eth_private_key(eth_private_key);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_private_key(DEFAULT_ETH_PRIVATE_KEY);
+3 -3
View File
@@ -95,7 +95,7 @@ fn parse_package_version() -> Version {
fn minor_0_12_upgrade(
mut config: Config,
_matches: &ArgMatches<'_>,
_matches: &ArgMatches,
config_version: &Version,
package_version: &Version,
) -> Config {
@@ -131,7 +131,7 @@ fn minor_0_12_upgrade(
config
}
fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Version) {
fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version) {
loop {
let config_version = parse_config_version(&config);
@@ -151,7 +151,7 @@ fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Ver
}
}
pub fn execute(matches: &ArgMatches<'_>) {
pub fn execute(matches: &ArgMatches) {
let package_version = parse_package_version();
let id = matches.value_of("id").unwrap();
+1 -1
View File
@@ -2,7 +2,7 @@
name = "websocket-requests"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1 -1
View File
@@ -2,7 +2,7 @@
name = "nym-socks5-client"
version = "0.12.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
edition = "2018"
rust-version = "1.56"
[lib]
+7 -11
View File
@@ -59,6 +59,12 @@ eth_endpoint = '{{ client.eth_endpoint }}'
##### additional client config options #####
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_id }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_listener }}'
# A gateway specific, optional, base58 stringified shared key used for
# communication with particular gateway.
gateway_shared_key_file = '{{ client.gateway_shared_key_file }}'
@@ -66,22 +72,12 @@ gateway_shared_key_file = '{{ client.gateway_shared_key_file }}'
# Path to file containing key used for encrypting and decrypting the content of an
# acknowledgement so that nobody besides the client knows which packet it refers to.
ack_key_file = '{{ client.ack_key_file }}'
##### advanced configuration options #####
# Absolute path to the home Nym Clients directory.
nym_root_directory = '{{ client.nym_root_directory }}'
[client.gateway_endpoint]
# ID of the gateway from which the client should be fetching messages.
gateway_id = '{{ client.gateway_endpoint.gateway_id }}'
# Address of the gateway owner to which the client should send messages.
gateway_owner = '{{ client.gateway_endpoint.gateway_owner }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_endpoint.gateway_listener }}'
##### socket config options #####
-5
View File
@@ -148,10 +148,6 @@ impl NymClient {
if gateway_id.is_empty() {
panic!("The identity of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_owner = self.config.get_base().get_gateway_owner();
if gateway_owner.is_empty() {
panic!("The owner of the gateway is unknown - did you run `nym-client` init?")
}
let gateway_address = self.config.get_base().get_gateway_listener();
if gateway_address.is_empty() {
panic!("The address of the gateway is unknown - did you run `nym-client` init?")
@@ -177,7 +173,6 @@ impl NymClient {
gateway_address,
self.key_manager.identity_keypair(),
gateway_identity,
gateway_owner,
Some(self.key_manager.gateway_shared_key()),
mixnet_message_sender,
ack_sender,
+6 -6
View File
@@ -136,7 +136,6 @@ async fn register_with_gateway(
let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(),
gateway.identity_key,
gateway.owner.clone(),
our_identity.clone(),
timeout,
);
@@ -257,14 +256,15 @@ pub async fn execute(matches: ArgMatches<'static>) {
chosen_gateway_id,
)
.await;
config
.get_base_mut()
.with_gateway_id(gateway_details.identity_key.to_base58_string());
let shared_keys =
register_with_gateway(&gateway_details, key_manager.identity_keypair()).await;
config.get_base_mut().with_gateway_endpoint(
gateway_details.identity_key.to_base58_string(),
gateway_details.owner.clone(),
gateway_details.clients_address(),
);
config
.get_base_mut()
.with_gateway_listener(gateway_details.clients_address());
key_manager.insert_gateway_shared_key(shared_keys);
let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base());
+3 -3
View File
@@ -32,7 +32,7 @@ fn parse_validators(raw: &str) -> Vec<Url> {
.collect()
}
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> Config {
pub(crate) fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if let Some(raw_validators) = matches.value_of("validators") {
config
.get_base_mut()
@@ -54,7 +54,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_endpoint) = matches.value_of(ETH_ENDPOINT_ARG_NAME) {
config.get_base_mut().with_eth_endpoint(eth_endpoint);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_endpoint(DEFAULT_ETH_ENDPOINT);
@@ -62,7 +62,7 @@ pub(crate) fn override_config(mut config: Config, matches: &ArgMatches<'_>) -> C
#[cfg(not(feature = "coconut"))]
if let Some(eth_private_key) = matches.value_of(ETH_PRIVATE_KEY_ARG_NAME) {
config.get_base_mut().with_eth_private_key(eth_private_key);
} else if !cfg!(feature = "eth") {
} else {
config
.get_base_mut()
.with_eth_private_key(DEFAULT_ETH_PRIVATE_KEY);
+3 -3
View File
@@ -95,7 +95,7 @@ fn parse_package_version() -> Version {
fn minor_0_12_upgrade(
mut config: Config,
_matches: &ArgMatches<'_>,
_matches: &ArgMatches,
config_version: &Version,
package_version: &Version,
) -> Config {
@@ -131,7 +131,7 @@ fn minor_0_12_upgrade(
config
}
fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Version) {
fn do_upgrade(mut config: Config, matches: &ArgMatches, package_version: Version) {
loop {
let config_version = parse_config_version(&config);
@@ -151,7 +151,7 @@ fn do_upgrade(mut config: Config, matches: &ArgMatches<'_>, package_version: Ver
}
}
pub fn execute(matches: &ArgMatches<'_>) {
pub fn execute(matches: &ArgMatches) {
let package_version = parse_package_version();
let id = matches.value_of("id").unwrap();
+7 -17
View File
@@ -11,7 +11,6 @@
"@tauri-apps/api": "^1.0.0-beta.4",
"compression": "^1.7.1",
"polka": "next",
"qrious": "^4.0.2",
"sirv": "^1.0.0"
},
"devDependencies": {
@@ -6759,11 +6758,6 @@
"node": ">=8"
}
},
"node_modules/qrious": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/qrious/-/qrious-4.0.2.tgz",
"integrity": "sha512-xWPJIrK1zu5Ypn898fBp8RHkT/9ibquV2Kv24S/JY9VYEhMBMKur1gHVsOiNUh7PHP9uCgejjpZUHUIXXKoU/g=="
},
"node_modules/query-string": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
@@ -7585,10 +7579,11 @@
"license": "MIT"
},
"node_modules/simple-get": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
"dev": true,
"license": "MIT",
"dependencies": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
@@ -13479,11 +13474,6 @@
"escape-goat": "^2.0.0"
}
},
"qrious": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/qrious/-/qrious-4.0.2.tgz",
"integrity": "sha512-xWPJIrK1zu5Ypn898fBp8RHkT/9ibquV2Kv24S/JY9VYEhMBMKur1gHVsOiNUh7PHP9uCgejjpZUHUIXXKoU/g=="
},
"query-string": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
@@ -14046,9 +14036,9 @@
"dev": true
},
"simple-get": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
"dev": true,
"requires": {
"decompress-response": "^4.2.0",
+1 -1
View File
@@ -6,7 +6,7 @@ authors = ["you"]
license = ""
repository = ""
default-run = "app"
edition = "2021"
edition = "2018"
build = "src/build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+7 -7
View File
@@ -1813,7 +1813,7 @@ decompress-response@^3.2.0, decompress-response@^3.3.0:
decompress-response@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz"
integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
dependencies:
mimic-response "^2.0.0"
@@ -3130,7 +3130,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
mimic-response@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz"
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
mimic-response@^3.1.0:
@@ -4056,13 +4056,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
simple-concat@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz"
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^3.0.3, simple-get@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55"
integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==
version "3.1.0"
resolved "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz"
integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==
dependencies:
decompress-response "^4.2.0"
once "^1.3.1"
@@ -4673,7 +4673,7 @@ wrap-ansi@^7.0.0:
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
write-file-atomic@^3.0.0:
+2 -2
View File
@@ -180,8 +180,8 @@ export default class ValidatorClient implements INymClient {
return this.client.getSybilResistancePercent(this.mixnetContract);
}
public async getIntervalRewardPercent(): Promise<number> {
return this.client.getIntervalRewardPercent(this.mixnetContract);
public async getEpochRewardPercent(): Promise<number> {
return this.client.getEpochRewardPercent(this.mixnetContract);
}
public async getAllNymdMixnodes(): Promise<MixNodeBond[]> {
+9 -2
View File
@@ -18,6 +18,7 @@ import {
PagedGatewayResponse,
PagedMixDelegationsResponse,
PagedMixnodeResponse,
RewardingIntervalResponse,
RewardingStatus,
} from './types';
@@ -78,6 +79,12 @@ export default class NymdQuerier implements INymdQuery {
});
}
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse> {
return this.client.queryContractSmart(mixnetContractAddress, {
current_rewarding_interval: {},
});
}
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
limit?: number,
@@ -148,9 +155,9 @@ export default class NymdQuerier implements INymdQuery {
});
}
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
getEpochRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.client.queryContractSmart(mixnetContractAddress, {
get_interval_reward_percent: {},
get_epoch_reward_percent: {},
});
}
+9 -3
View File
@@ -28,6 +28,7 @@ import {
PagedGatewayResponse,
PagedMixDelegationsResponse,
PagedMixnodeResponse,
RewardingIntervalResponse,
RewardingStatus,
} from './types';
import ValidatorApiQuerier, { IValidatorApiQuery } from './validator-api-querier';
@@ -62,6 +63,7 @@ export interface INymdQuery {
ownsMixNode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse>;
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse>;
getStateParams(mixnetContractAddress: string): Promise<ContractStateParams>;
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse>;
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
@@ -85,7 +87,7 @@ export interface INymdQuery {
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution>;
getRewardPool(mixnetContractAddress: string): Promise<string>;
getCirculatingSupply(mixnetContractAddress: string): Promise<string>;
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number>;
getEpochRewardPercent(mixnetContractAddress: string): Promise<number>;
getSybilResistancePercent(mixnetContractAddress: string): Promise<number>;
getRewardingStatus(
mixnetContractAddress: string,
@@ -136,6 +138,10 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient
return this.nymdQuerier.getStateParams(mixnetContractAddress);
}
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse> {
return this.nymdQuerier.getCurrentRewardingInterval(mixnetContractAddress);
}
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
limit?: number,
@@ -178,8 +184,8 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient
return this.nymdQuerier.getCirculatingSupply(mixnetContractAddress);
}
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getIntervalRewardPercent(mixnetContractAddress);
getEpochRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getEpochRewardPercent(mixnetContractAddress);
}
getSybilResistancePercent(mixnetContractAddress: string): Promise<number> {
+7 -2
View File
@@ -31,6 +31,7 @@ import {
PagedGatewayResponse,
PagedMixDelegationsResponse,
PagedMixnodeResponse,
RewardingIntervalResponse,
RewardingStatus,
} from './types';
import ValidatorApiQuerier from './validator-api-querier';
@@ -256,6 +257,10 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
return this.nymdQuerier.getStateParams(mixnetContractAddress);
}
getCurrentRewardingInterval(mixnetContractAddress: string): Promise<RewardingIntervalResponse> {
return this.nymdQuerier.getCurrentRewardingInterval(mixnetContractAddress);
}
getAllNetworkDelegationsPaged(
mixnetContractAddress: string,
limit?: number,
@@ -298,8 +303,8 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
return this.nymdQuerier.getCirculatingSupply(mixnetContractAddress);
}
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getIntervalRewardPercent(mixnetContractAddress);
getEpochRewardPercent(mixnetContractAddress: string): Promise<number> {
return this.nymdQuerier.getEpochRewardPercent(mixnetContractAddress);
}
getSybilResistancePercent(mixnetContractAddress: string): Promise<number> {
+6
View File
@@ -43,6 +43,12 @@ export type ContractStateParams = {
mixnode_active_set_size: number;
};
export type RewardingIntervalResponse = {
current_rewarding_interval_starting_block: number;
current_rewarding_interval_nonce: number;
rewarding_in_progress: boolean;
};
export type LayerDistribution = {
gateways: number;
layer1: number;
+3 -3
View File
@@ -2,7 +2,7 @@
name = "nym-client-wasm"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "0.12.0"
edition = "2021"
edition = "2018"
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"]
license = "Apache-2.0"
repository = "https://github.com/nymtech/nym"
@@ -20,7 +20,7 @@ coconut = ["coconut-interface", "credentials", "gateway-client/coconut"]
[dependencies]
futures = "0.3"
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = { version = "=0.2.78", features = ["serde-serialize"] }
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
wasm-bindgen-futures = "0.4"
js-sys = "0.3"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
@@ -32,7 +32,7 @@ credentials = { path = "../../common/credentials", optional = true }
crypto = { path = "../../common/crypto" }
nymsphinx = { path = "../../common/nymsphinx" }
topology = { path = "../../common/topology" }
gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm"] }
gateway-client = { path = "../../common/client-libs/gateway-client" }
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
wasm-utils = { path = "../../common/wasm-utils" }
+16 -19
View File
@@ -22,10 +22,7 @@
"webpack-dev-server": "^3.11.0"
}
},
"../pkg": {
"name": "@nymproject/nym-client-wasm",
"version": "0.0.1"
},
"../pkg": {},
"node_modules/@nymproject/nym-client-wasm": {
"resolved": "../pkg",
"link": true
@@ -2354,9 +2351,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true,
"funding": [
{
@@ -5862,9 +5859,9 @@
}
},
"node_modules/url-parse": {
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"dependencies": {
"querystringify": "^2.1.1",
@@ -8545,9 +8542,9 @@
}
},
"follow-redirects": {
"version": "1.14.8",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
"dev": true
},
"for-in": {
@@ -11402,9 +11399,9 @@
}
},
"url-parse": {
"version": "1.5.7",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",
@@ -11904,9 +11901,9 @@
"dev": true
},
"ws": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"dev": true,
"requires": {
"async-limiter": "~1.0.0"
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,7 @@
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"bootstrap": "^4.5.0",
"node-sass": "^7.0.0",
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "^4.0.0",
+2 -2
View File
@@ -3,6 +3,7 @@
use crypto::asymmetric::{encryption, identity};
use futures::channel::mpsc;
use gateway_client::bandwidth::BandwidthController;
use gateway_client::GatewayClient;
use nymsphinx::acknowledgements::AckKey;
use nymsphinx::addressing::clients::Recipient;
@@ -110,7 +111,7 @@ impl NymClient {
let testnet_mode = self.testnet_mode;
#[cfg(feature = "coconut")]
let bandwidth_controller = Some(gateway_client::bandwidth::BandwidthController::new(
let bandwidth_controller = Some(BandwidthController::new(
vec![self.validator_server.clone()],
*self.identity.public_key(),
));
@@ -127,7 +128,6 @@ impl NymClient {
gateway.clients_address(),
Arc::clone(&client.identity),
gateway.identity_key,
gateway.owner.clone(),
None,
mixnet_messages_sender,
ack_sender,
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "bandwidth-claim-contract"
version = "0.1.0"
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+8 -7
View File
@@ -2,7 +2,7 @@
name = "gateway-client"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -15,15 +15,12 @@ log = "0.4"
thiserror = "1.0"
url = "2.2"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
secp256k1 = "0.20.3"
web3 = { version = "0.17.0", default-features = false }
# internal
credentials = { path = "../../credentials" }
crypto = { path = "../../crypto" }
gateway-requests = { path = "../../../gateway/gateway-requests" }
nymsphinx = { path = "../../nymsphinx" }
pemstore = { path = "../../pemstore" }
coconut-interface = { path = "../../coconut-interface", optional = true }
network-defaults = { path = "../../network-defaults" }
@@ -39,6 +36,12 @@ features = ["macros", "rt", "net", "sync", "time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite]
version = "0.14"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.secp256k1]
version = "0.20.3"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.web3]
version = "0.17.0"
# wasm-only dependencies
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
version = "0.2"
@@ -67,6 +70,4 @@ features = ["js"]
#url = "2.1"
[features]
coconut = ["gateway-requests/coconut", "coconut-interface"]
wasm = ["web3/wasm", "web3/http", "web3/signing"]
default = ["web3/default"]
coconut = ["gateway-requests/coconut", "coconut-interface"]
@@ -16,27 +16,22 @@ use crypto::asymmetric::identity::PublicKey;
use network_defaults::BANDWIDTH_VALUE;
#[cfg(not(feature = "coconut"))]
use network_defaults::{
eth_contract::ETH_ERC20_JSON_ABI, eth_contract::ETH_JSON_ABI, ETH_BURN_FUNCTION_NAME,
ETH_CONTRACT_ADDRESS, ETH_ERC20_APPROVE_FUNCTION_NAME, ETH_ERC20_CONTRACT_ADDRESS,
ETH_MIN_BLOCK_DEPTH, TOKENS_TO_BURN, UTOKENS_TO_BURN,
eth_contract::ETH_JSON_ABI, ETH_BURN_FUNCTION_NAME, ETH_CONTRACT_ADDRESS, ETH_MIN_BLOCK_DEPTH,
TOKENS_TO_BURN,
};
#[cfg(not(feature = "coconut"))]
use pemstore::traits::PemStorableKeyPair;
#[cfg(not(feature = "coconut"))]
use rand::rngs::OsRng;
#[cfg(not(feature = "coconut"))]
use secp256k1::SecretKey;
#[cfg(not(feature = "coconut"))]
use std::io::{Read, Write};
use std::io::Write;
#[cfg(not(feature = "coconut"))]
use std::str::FromStr;
#[cfg(not(feature = "coconut"))]
use web3::{
contract::{Contract, Options},
ethabi::Token,
signing::{Key, SecretKeyRef},
transports::Http,
types::{Address, U256, U64},
types::{Address, Bytes, U256, U64},
Web3,
};
@@ -55,19 +50,6 @@ pub fn eth_contract(web3: Web3<Http>) -> Contract<Http> {
.expect("Invalid json abi")
}
#[cfg(not(feature = "coconut"))]
pub fn eth_erc20_contract(web3: Web3<Http>) -> Contract<Http> {
Contract::from_json(
web3.eth(),
Address::from(ETH_ERC20_CONTRACT_ADDRESS),
json::parse(ETH_ERC20_JSON_ABI)
.expect("Invalid json abi")
.dump()
.as_bytes(),
)
.expect("Invalid json abi")
}
#[derive(Clone)]
pub struct BandwidthController {
#[cfg(feature = "coconut")]
@@ -77,8 +59,6 @@ pub struct BandwidthController {
#[cfg(not(feature = "coconut"))]
contract: Contract<Http>,
#[cfg(not(feature = "coconut"))]
erc20_contract: Contract<Http>,
#[cfg(not(feature = "coconut"))]
eth_private_key: SecretKey,
#[cfg(not(feature = "coconut"))]
backup_bandwidth_token_keys_dir: std::path::PathBuf,
@@ -104,14 +84,12 @@ impl BandwidthController {
Http::new(&eth_endpoint).map_err(|_| GatewayClientError::InvalidURL(eth_endpoint))?;
let web3 = web3::Web3::new(transport);
// Fail early, on invalid abi
let contract = eth_contract(web3.clone());
let erc20_contract = eth_erc20_contract(web3);
let contract = eth_contract(web3);
let eth_private_key = secp256k1::SecretKey::from_str(&eth_private_key)
.map_err(|_| GatewayClientError::InvalidEthereumPrivateKey)?;
Ok(BandwidthController {
contract,
erc20_contract,
eth_private_key,
backup_bandwidth_token_keys_dir,
})
@@ -129,45 +107,6 @@ impl BandwidthController {
Ok(())
}
#[cfg(not(feature = "coconut"))]
fn restore_keypair(&self) -> Result<identity::KeyPair, GatewayClientError> {
std::fs::create_dir_all(&self.backup_bandwidth_token_keys_dir)?;
let file = std::fs::read_dir(&self.backup_bandwidth_token_keys_dir)?
.find(|entry| {
entry
.as_ref()
.map(|entry| entry.path().is_file())
.unwrap_or(false)
})
.unwrap_or_else(|| Err(std::io::Error::from(std::io::ErrorKind::NotFound)))?;
let file_path = file.path();
let pub_key = file_path
.file_name()
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::NotFound))?
.to_str()
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::NotFound))?;
let mut priv_key = vec![];
std::fs::File::open(file_path.clone())?.read_to_end(&mut priv_key)?;
Ok(identity::KeyPair::from_keys(
identity::PrivateKey::from_bytes(&priv_key).unwrap(),
identity::PublicKey::from_base58_string(pub_key).unwrap(),
))
}
#[cfg(not(feature = "coconut"))]
fn mark_keypair_as_spent(&self, keypair: &identity::KeyPair) -> Result<(), GatewayClientError> {
let mut spent_dir = self.backup_bandwidth_token_keys_dir.clone();
spent_dir.push("spent");
std::fs::create_dir_all(&spent_dir)?;
let file_path_old = self
.backup_bandwidth_token_keys_dir
.join(keypair.public_key().to_base58_string());
let file_path_new = spent_dir.join(keypair.public_key().to_base58_string());
std::fs::rename(file_path_old, file_path_new)?;
Ok(())
}
#[cfg(feature = "coconut")]
pub async fn prepare_coconut_credential(
&self,
@@ -206,25 +145,17 @@ impl BandwidthController {
pub async fn prepare_token_credential(
&self,
gateway_identity: PublicKey,
gateway_owner: String,
) -> Result<TokenCredential, GatewayClientError> {
let kp = match self.restore_keypair() {
Ok(kp) => kp,
Err(_) => {
let mut rng = OsRng;
let kp = identity::KeyPair::new(&mut rng);
self.backup_keypair(&kp)?;
kp
}
};
let mut rng = OsRng;
let kp = identity::KeyPair::new(&mut rng);
self.backup_keypair(&kp)?;
let verification_key = *kp.public_key();
let signed_verification_key = kp.private_key().sign(&verification_key.to_bytes());
self.buy_token_credential(verification_key, signed_verification_key, gateway_owner)
self.buy_token_credential(verification_key, signed_verification_key)
.await?;
self.mark_keypair_as_spent(&kp)?;
let message: Vec<u8> = verification_key
.to_bytes()
.iter()
@@ -246,114 +177,33 @@ impl BandwidthController {
&self,
verification_key: PublicKey,
signed_verification_key: identity::Signature,
gateway_owner: String,
) -> Result<(), GatewayClientError> {
// 0 means a transaction failure, 1 means success
let confirmations = if cfg!(debug_assertions) {
1
} else {
ETH_MIN_BLOCK_DEPTH
};
// 15 seconds per confirmation block + 10 seconds of network overhead + 20 seconds of wait for kill
// 15 seconds per confirmation block + 10 seconds of network overhead
log::info!(
"Waiting for Ethereum transaction. This should take about {} seconds",
(confirmations + 1) * 15 + 30
confirmations * 15 + 10
);
let mut options = Options::default();
let estimation = self
.erc20_contract
.estimate_gas(
ETH_ERC20_APPROVE_FUNCTION_NAME,
(
Token::Address(Address::from(ETH_CONTRACT_ADDRESS)),
Token::Uint(U256::from(UTOKENS_TO_BURN)),
),
SecretKeyRef::from(&self.eth_private_key).address(),
options.clone(),
)
.await?;
options.gas = Some(estimation);
log::info!("Calling ERC20 approve in 10 seconds with an estimated gas of {}. Kill the process if you want to abort", estimation);
#[cfg(not(target_arch = "wasm32"))]
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
#[cfg(target_arch = "wasm32")]
if let Err(err) = fluvio_wasm_timer::Delay::new(std::time::Duration::from_secs(10)).await {
log::error!(
"the timer has gone away while waiting for possible kill! - {}",
err
);
}
let recipt = self
.erc20_contract
.signed_call_with_confirmations(
ETH_ERC20_APPROVE_FUNCTION_NAME,
(
Token::Address(Address::from(ETH_CONTRACT_ADDRESS)),
Token::Uint(U256::from(UTOKENS_TO_BURN)),
),
options,
1, // One confirmation is enough, as we'll be consuming the approved token next anyway
&self.eth_private_key,
)
.await?;
if Some(U64::from(0u64)) == recipt.status {
return Err(GatewayClientError::BurnTokenError(
web3::Error::InvalidResponse(format!(
"Approve transaction status is 0 (failure): {:?}",
recipt.logs,
)),
));
} else {
log::info!(
"Approved {} tokens for bandwidth use on Ethereum",
TOKENS_TO_BURN
);
}
let mut options = Options::default();
let estimation = self
.contract
.estimate_gas(
ETH_BURN_FUNCTION_NAME,
(
Token::Uint(U256::from(UTOKENS_TO_BURN)),
Token::Uint(U256::from(&verification_key.to_bytes())),
Token::Bytes(signed_verification_key.to_bytes().to_vec()),
Token::String(gateway_owner.clone()),
),
SecretKeyRef::from(&self.eth_private_key).address(),
options.clone(),
)
.await?;
options.gas = Some(estimation);
log::info!("Generating bandwidth on ETH contract in 10 seconds with an estimated gas of {}. \
Kill the process if you want to abort. Keep in mind that if you abort now, you'll still have \
some tokens approved for bandwidth spending from the previous action. \
If you don't want that, you'll need to manually decreaseAllowance to revert the approval.", estimation);
#[cfg(not(target_arch = "wasm32"))]
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
#[cfg(target_arch = "wasm32")]
if let Err(err) = fluvio_wasm_timer::Delay::new(std::time::Duration::from_secs(10)).await {
log::error!(
"the timer has gone away while waiting for possible kill! - {}",
err
);
}
let recipt = self
.contract
.signed_call_with_confirmations(
ETH_BURN_FUNCTION_NAME,
(
Token::Uint(U256::from(UTOKENS_TO_BURN)),
Token::Uint(U256::from(&verification_key.to_bytes())),
Token::Bytes(signed_verification_key.to_bytes().to_vec()),
Token::String(gateway_owner),
U256::from(TOKENS_TO_BURN),
U256::from(&verification_key.to_bytes()),
Bytes(signed_verification_key.to_bytes().to_vec()),
),
options,
Options::default(),
confirmations,
&self.eth_private_key,
)
.await?;
if Some(U64::from(0u64)) == recipt.status {
if Some(U64::from(0)) == recipt.status {
Err(GatewayClientError::BurnTokenError(
web3::Error::InvalidResponse(format!(
"Transaction status is 0 (failure): {:?}",
@@ -386,15 +236,6 @@ mod tests {
eth_contract(web3);
}
#[test]
fn parse_erc20_contract() {
let transport =
Http::new("https://rinkeby.infura.io/v3/00000000000000000000000000000000").unwrap();
let web3 = web3::Web3::new(transport);
// test no panic occurs
eth_erc20_contract(web3);
}
#[test]
fn check_event_name_constant_against_abi() {
let transport =
+19 -23
View File
@@ -20,7 +20,6 @@ use gateway_requests::iv::IV;
use gateway_requests::registration::handshake::{client_handshake, SharedKeys};
use gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse};
use log::*;
use network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN};
use nymsphinx::forwarding::packet::MixPacket;
use rand::rngs::OsRng;
use std::convert::TryFrom;
@@ -45,7 +44,6 @@ pub struct GatewayClient {
bandwidth_remaining: i64,
gateway_address: String,
gateway_identity: identity::PublicKey,
gateway_owner: String,
local_identity: Arc<identity::KeyPair>,
shared_key: Option<Arc<SharedKeys>>,
connection: SocketState,
@@ -70,7 +68,6 @@ impl GatewayClient {
gateway_address: String,
local_identity: Arc<identity::KeyPair>,
gateway_identity: identity::PublicKey,
gateway_owner: String,
shared_key: Option<Arc<SharedKeys>>,
mixnet_message_sender: MixnetMessageSender,
ack_sender: AcknowledgementSender,
@@ -83,7 +80,6 @@ impl GatewayClient {
bandwidth_remaining: 0,
gateway_address,
gateway_identity,
gateway_owner,
local_identity,
shared_key,
connection: SocketState::NotConnected,
@@ -116,7 +112,6 @@ impl GatewayClient {
pub fn new_init(
gateway_address: String,
gateway_identity: identity::PublicKey,
gateway_owner: String,
local_identity: Arc<identity::KeyPair>,
response_timeout_duration: Duration,
) -> Self {
@@ -134,7 +129,6 @@ impl GatewayClient {
bandwidth_remaining: 0,
gateway_address,
gateway_identity,
gateway_owner,
local_identity,
shared_key: None,
connection: SocketState::NotConnected,
@@ -554,8 +548,6 @@ impl GatewayClient {
return self.try_claim_testnet_bandwidth().await;
}
let _gateway_owner = self.gateway_owner.clone();
#[cfg(feature = "coconut")]
let credential = self
.bandwidth_controller
@@ -568,7 +560,7 @@ impl GatewayClient {
.bandwidth_controller
.as_ref()
.unwrap()
.prepare_token_credential(self.gateway_identity, _gateway_owner)
.prepare_token_credential(self.gateway_identity)
.await?;
#[cfg(feature = "coconut")]
@@ -592,10 +584,15 @@ impl GatewayClient {
return Err(GatewayClientError::NotAuthenticated);
}
if self.estimate_required_bandwidth(&packets) > self.bandwidth_remaining {
return Err(GatewayClientError::NotEnoughBandwidth(
self.estimate_required_bandwidth(&packets),
self.bandwidth_remaining,
));
// Try to claim more bandwidth first, and return an error only if that is still not
// enough (the current granularity for bandwidth should be sufficient)
self.claim_bandwidth().await?;
if self.estimate_required_bandwidth(&packets) > self.bandwidth_remaining {
return Err(GatewayClientError::NotEnoughBandwidth(
self.estimate_required_bandwidth(&packets),
self.bandwidth_remaining,
));
}
}
if !self.connection.is_established() {
return Err(GatewayClientError::ConnectionNotEstablished);
@@ -662,10 +659,15 @@ impl GatewayClient {
return Err(GatewayClientError::NotAuthenticated);
}
if (mix_packet.sphinx_packet().len() as i64) > self.bandwidth_remaining {
return Err(GatewayClientError::NotEnoughBandwidth(
mix_packet.sphinx_packet().len() as i64,
self.bandwidth_remaining,
));
// Try to claim more bandwidth first, and return an error only if that is still not
// enough
self.claim_bandwidth().await?;
if (mix_packet.sphinx_packet().len() as i64) > self.bandwidth_remaining {
return Err(GatewayClientError::NotEnoughBandwidth(
mix_packet.sphinx_packet().len() as i64,
self.bandwidth_remaining,
));
}
}
if !self.connection.is_established() {
return Err(GatewayClientError::ConnectionNotEstablished);
@@ -735,12 +737,6 @@ impl GatewayClient {
}
let shared_key = self.perform_initial_authentication().await?;
if self.bandwidth_remaining < REMAINING_BANDWIDTH_THRESHOLD {
info!("Claiming more bandwidth for your tokens. This will use {} token(s) from your wallet. \
Stop the process now if you don't want that to happen.", TOKENS_TO_BURN);
self.claim_bandwidth().await?;
}
// this call is NON-blocking
self.start_listening_for_mixnet_messages()?;
@@ -8,7 +8,7 @@ use tungstenite::Error as WsError;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::JsValue;
#[cfg(not(feature = "coconut"))]
use web3::{contract::Error as Web3ContractError, Error as Web3Error};
use web3::Error as Web3Error;
#[derive(Debug, Error)]
pub enum GatewayClientError {
@@ -27,17 +27,13 @@ pub enum GatewayClientError {
NetworkErrorWasm(JsValue),
#[cfg(not(feature = "coconut"))]
#[error("Keypair IO error - {0}")]
#[error("Could not backup keypair - {0}")]
IOError(#[from] std::io::Error),
#[cfg(not(feature = "coconut"))]
#[error("Could not burn ERC20 token in Ethereum smart contract - {0}")]
BurnTokenError(#[from] Web3Error),
#[cfg(not(feature = "coconut"))]
#[error("Could not run web3 contract - {0}")]
Web3ContractError(#[from] Web3ContractError),
#[cfg(not(feature = "coconut"))]
#[error("Invalid Ethereum private key")]
InvalidEthereumPrivateKey,
+1 -1
View File
@@ -2,7 +2,7 @@
name = "mixnet-client"
version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+3 -14
View File
@@ -41,17 +41,6 @@ impl Config {
}
}
pub trait SendWithoutResponse {
// Without response in this context means we will not listen for anything we might get back (not
// that we should get anything), including any possible io errors
fn send_without_response(
&mut self,
address: NymNodeRoutingAddress,
packet: SphinxPacket,
packet_mode: PacketMode,
) -> io::Result<()>;
}
pub struct Client {
conn_new: HashMap<NymNodeRoutingAddress, ConnectionSender>,
config: Config,
@@ -197,10 +186,10 @@ impl Client {
.await
});
}
}
impl SendWithoutResponse for Client {
fn send_without_response(
// without response in this context means we will not listen for anything we might get back
// (not that we should get anything), including any possible io errors
pub fn send_without_response(
&mut self,
address: NymNodeRoutingAddress,
packet: SphinxPacket,
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::{Client, Config, SendWithoutResponse};
use crate::client::{Client, Config};
use futures::channel::mpsc;
use futures::StreamExt;
use log::*;
+1 -1
View File
@@ -4,4 +4,4 @@
pub mod client;
pub mod forwarder;
pub use client::{Client, Config, SendWithoutResponse};
pub use client::{Client, Config};
+7 -23
View File
@@ -2,7 +2,7 @@
name = "validator-client"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
rust-version = "1.56"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -10,11 +10,10 @@ rust-version = "1.56"
[dependencies]
base64 = "0.13"
mixnet-contract-common = { path= "../../cosmwasm-smart-contracts/mixnet-contract" }
vesting-contract-common = { path= "../../cosmwasm-smart-contracts/vesting-contract" }
vesting-contract = { path = "../../../contracts/vesting" }
serde = { version = "1", features = ["derive"] }
vesting-contract = { path="../../../contracts/vesting" }
serde = { version="1", features=["derive"] }
serde_json = "1"
reqwest = { version = "0.11", features = ["json"] }
reqwest = { version="0.11", features=["json"] }
thiserror = "1"
log = "0.4"
url = { version = "2.2", features = ["serde"] }
@@ -29,29 +28,14 @@ validator-api-requests = { path = "../../../validator-api/validator-api-requests
async-trait = { version = "0.1.51", optional = true }
bip39 = { version = "1", features = ["rand"], optional = true }
config = { path = "../../config", optional = true }
cosmrs = { version = "0.4.1", features = [
"rpc",
"bip32",
"cosmwasm",
], optional = true }
cosmrs = { version = "0.4.1", features = ["rpc", "bip32", "cosmwasm"], optional = true }
prost = { version = "0.9", default-features = false, optional = true }
flate2 = { version = "1.0.20", optional = true }
sha2 = { version = "0.9.5", optional = true }
itertools = { version = "0.10", optional = true }
cosmwasm-std = { version = "1.0.0-beta3", optional = true }
# Leaving it as * so that it inherits whatever the wallet is using
ts-rs = { version = "*", optional = true }
ts-rs = {version = "5.1", optional = true}
[features]
nymd-client = [
"async-trait",
"bip39",
"config",
"cosmrs",
"prost",
"flate2",
"sha2",
"itertools",
"cosmwasm-std",
]
nymd-client = ["async-trait", "bip39", "config", "cosmrs", "prost", "flate2", "sha2", "itertools", "cosmwasm-std"]
typescript-types = ["ts-rs", "validator-api-requests/ts-rs"]
+23 -196
View File
@@ -1,15 +1,6 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{validator_api, ValidatorClientError};
use coconut_interface::{BlindSignRequestBody, BlindedSignatureResponse, VerificationKeyResponse};
use mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixNodeBond};
use url::Url;
use validator_api_requests::models::{
CoreNodeStatusResponse, MixnodeStatusResponse, RewardEstimationResponse,
StakeSaturationResponse,
};
#[cfg(feature = "nymd-client")]
use crate::nymd::{
error::NymdError, CosmWasmClient, NymdClient, QueryNymdClient, SigningNymdClient,
@@ -17,53 +8,51 @@ use crate::nymd::{
#[cfg(feature = "nymd-client")]
use mixnet_contract_common::ContractStateParams;
use crate::{validator_api, ValidatorClientError};
use coconut_interface::{BlindSignRequestBody, BlindedSignatureResponse, VerificationKeyResponse};
#[cfg(feature = "nymd-client")]
use mixnet_contract_common::{
Delegation, IdentityKey, Interval, MixnetContractVersion, MixnodeRewardingStatusResponse,
RewardedSetNodeStatus, RewardedSetUpdateDetails,
Delegation, MixnetContractVersion, MixnodeRewardingStatusResponse, RewardingIntervalResponse,
};
#[cfg(feature = "nymd-client")]
use std::collections::{HashMap, HashSet};
use mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixNodeBond};
#[cfg(feature = "nymd-client")]
use std::str::FromStr;
use url::Url;
use validator_api_requests::models::{
CoreNodeStatusResponse, MixnodeStatusResponse, RewardEstimationResponse,
StakeSaturationResponse,
};
#[cfg(feature = "nymd-client")]
#[must_use]
pub struct Config {
network: network_defaults::all::Network,
api_url: Url,
nymd_url: Url,
mixnet_contract_address: Option<cosmrs::AccountId>,
vesting_contract_address: Option<cosmrs::AccountId>,
erc20_bridge_contract_address: Option<cosmrs::AccountId>,
mixnode_page_limit: Option<u32>,
gateway_page_limit: Option<u32>,
mixnode_delegations_page_limit: Option<u32>,
rewarded_set_page_limit: Option<u32>,
}
#[cfg(feature = "nymd-client")]
impl Config {
pub fn new(
network: network_defaults::all::Network,
nymd_url: Url,
api_url: Url,
mixnet_contract_address: Option<cosmrs::AccountId>,
vesting_contract_address: Option<cosmrs::AccountId>,
erc20_bridge_contract_address: Option<cosmrs::AccountId>,
) -> Self {
Config {
network,
nymd_url,
mixnet_contract_address,
vesting_contract_address,
erc20_bridge_contract_address,
api_url,
mixnode_page_limit: None,
gateway_page_limit: None,
mixnode_delegations_page_limit: None,
rewarded_set_page_limit: None,
}
}
@@ -81,25 +70,17 @@ impl Config {
self.mixnode_delegations_page_limit = limit;
self
}
pub fn with_rewarded_set_page_limit(mut self, limit: Option<u32>) -> Config {
self.rewarded_set_page_limit = limit;
self
}
}
#[cfg(feature = "nymd-client")]
pub struct Client<C> {
network: network_defaults::all::Network,
mixnet_contract_address: Option<cosmrs::AccountId>,
vesting_contract_address: Option<cosmrs::AccountId>,
erc20_bridge_contract_address: Option<cosmrs::AccountId>,
mnemonic: Option<bip39::Mnemonic>,
mixnode_page_limit: Option<u32>,
gateway_page_limit: Option<u32>,
mixnode_delegations_page_limit: Option<u32>,
rewarded_set_page_limit: Option<u32>,
// ideally they would have been read-only, but unfortunately rust doesn't have such features
pub validator_api: validator_api::Client,
@@ -114,25 +95,20 @@ impl Client<SigningNymdClient> {
) -> Result<Client<SigningNymdClient>, ValidatorClientError> {
let validator_api_client = validator_api::Client::new(config.api_url.clone());
let nymd_client = NymdClient::connect_with_mnemonic(
config.network,
config.nymd_url.as_str(),
config.mixnet_contract_address.clone(),
config.vesting_contract_address.clone(),
config.erc20_bridge_contract_address.clone(),
mnemonic.clone(),
None,
)?;
Ok(Client {
network: config.network,
mixnet_contract_address: config.mixnet_contract_address,
vesting_contract_address: config.vesting_contract_address,
erc20_bridge_contract_address: config.erc20_bridge_contract_address,
mnemonic: Some(mnemonic),
mixnode_page_limit: config.mixnode_page_limit,
gateway_page_limit: config.gateway_page_limit,
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
rewarded_set_page_limit: None,
validator_api: validator_api_client,
nymd: nymd_client,
})
@@ -140,11 +116,9 @@ impl Client<SigningNymdClient> {
pub fn change_nymd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> {
self.nymd = NymdClient::connect_with_mnemonic(
self.network,
new_endpoint.as_ref(),
self.mixnet_contract_address.clone(),
self.vesting_contract_address.clone(),
self.erc20_bridge_contract_address.clone(),
self.mnemonic.clone().unwrap(),
None,
)?;
@@ -166,29 +140,15 @@ impl Client<QueryNymdClient> {
cosmrs::AccountId::from_str(network_defaults::DEFAULT_VESTING_CONTRACT_ADDRESS)
.unwrap()
})),
Some(
config
.erc20_bridge_contract_address
.clone()
.unwrap_or_else(|| {
cosmrs::AccountId::from_str(
network_defaults::DEFAULT_BANDWIDTH_CLAIM_CONTRACT_ADDRESS,
)
.unwrap()
}),
),
)?;
Ok(Client {
network: config.network,
mixnet_contract_address: config.mixnet_contract_address,
vesting_contract_address: config.vesting_contract_address,
erc20_bridge_contract_address: config.erc20_bridge_contract_address,
mnemonic: None,
mixnode_page_limit: config.mixnode_page_limit,
gateway_page_limit: config.gateway_page_limit,
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
rewarded_set_page_limit: config.rewarded_set_page_limit,
validator_api: validator_api_client,
nymd: nymd_client,
})
@@ -199,7 +159,6 @@ impl Client<QueryNymdClient> {
new_endpoint.as_ref(),
self.mixnet_contract_address.clone(),
self.vesting_contract_address.clone(),
self.erc20_bridge_contract_address.clone(),
)?;
Ok(())
}
@@ -225,18 +184,6 @@ impl<C> Client<C> {
Ok(self.validator_api.get_mixnodes().await?)
}
pub async fn get_cached_rewarded_mixnodes(
&self,
) -> Result<Vec<MixNodeBond>, ValidatorClientError> {
Ok(self.validator_api.get_rewarded_mixnodes().await?)
}
pub async fn get_cached_active_mixnodes(
&self,
) -> Result<Vec<MixNodeBond>, ValidatorClientError> {
Ok(self.validator_api.get_active_mixnodes().await?)
}
pub async fn get_cached_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError> {
Ok(self.validator_api.get_gateways().await?)
}
@@ -255,6 +202,15 @@ impl<C> Client<C> {
Ok(self.nymd.get_mixnet_contract_version().await?)
}
pub async fn get_current_rewarding_interval(
&self,
) -> Result<RewardingIntervalResponse, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
Ok(self.nymd.get_current_rewarding_interval().await?)
}
pub async fn get_rewarding_status(
&self,
mix_identity: mixnet_contract_common::IdentityKey,
@@ -276,13 +232,6 @@ impl<C> Client<C> {
Ok(self.nymd.get_reward_pool().await?.u128())
}
pub async fn get_current_interval(&self) -> Result<Interval, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
Ok(self.nymd.get_current_interval().await?)
}
pub async fn get_circulating_supply(&self) -> Result<u128, ValidatorClientError>
where
C: CosmWasmClient + Sync,
@@ -297,136 +246,14 @@ impl<C> Client<C> {
Ok(self.nymd.get_sybil_resistance_percent().await?)
}
pub async fn get_active_set_work_factor(&self) -> Result<u8, ValidatorClientError>
pub async fn get_epoch_reward_percent(&self) -> Result<u8, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
Ok(self.nymd.get_active_set_work_factor().await?)
}
pub async fn get_interval_reward_percent(&self) -> Result<u8, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
Ok(self.nymd.get_interval_reward_percent().await?)
}
pub async fn get_current_rewarded_set_update_details(
&self,
) -> Result<RewardedSetUpdateDetails, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
Ok(self
.nymd
.query_current_rewarded_set_update_details()
.await?)
Ok(self.nymd.get_epoch_reward_percent().await?)
}
// basically handles paging for us
pub async fn get_all_nymd_rewarded_set_mixnode_identities(
&self,
) -> Result<Vec<(IdentityKey, RewardedSetNodeStatus)>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
let mut identities = Vec::new();
let mut start_after = None;
let mut height = None;
loop {
let mut paged_response = self
.nymd
.get_rewarded_set_identities_paged(
start_after.take(),
self.rewarded_set_page_limit,
height,
)
.await?;
identities.append(&mut paged_response.identities);
if height.is_none() {
// keep using the same height (the first query happened at the most recent height)
height = Some(paged_response.at_height)
}
if let Some(start_after_res) = paged_response.start_next_after {
start_after = Some(start_after_res)
} else {
break;
}
}
Ok(identities)
}
pub async fn get_nymd_rewarded_and_active_sets(
&self,
) -> Result<Vec<(MixNodeBond, RewardedSetNodeStatus)>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
let all_mixnodes = self.get_all_nymd_mixnodes().await?;
let rewarded_set_identities = self
.get_all_nymd_rewarded_set_mixnode_identities()
.await?
.into_iter()
.collect::<HashMap<_, _>>();
Ok(all_mixnodes
.into_iter()
.filter_map(|node| {
rewarded_set_identities
.get(node.identity())
.map(|status| (node, *status))
})
.collect())
}
/// If you need both rewarded and the active set, consider using [Self::get_nymd_rewarded_and_active_sets] instead
pub async fn get_nymd_rewarded_set(&self) -> Result<Vec<MixNodeBond>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
let all_mixnodes = self.get_all_nymd_mixnodes().await?;
let rewarded_set_identities = self
.get_all_nymd_rewarded_set_mixnode_identities()
.await?
.into_iter()
.map(|(identity, _status)| identity)
.collect::<HashSet<_>>();
Ok(all_mixnodes
.into_iter()
.filter(|node| rewarded_set_identities.contains(node.identity()))
.collect())
}
/// If you need both rewarded and the active set, consider using [Self::get_nymd_rewarded_and_active_sets] instead
pub async fn get_nymd_active_set(&self) -> Result<Vec<MixNodeBond>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
let all_mixnodes = self.get_all_nymd_mixnodes().await?;
let active_set_identities = self
.get_all_nymd_rewarded_set_mixnode_identities()
.await?
.into_iter()
.filter_map(|(identity, status)| {
if status.is_active() {
Some(identity)
} else {
None
}
})
.collect::<HashSet<_>>();
Ok(all_mixnodes
.into_iter()
.filter(|node| active_set_identities.contains(node.identity()))
.collect())
}
pub async fn get_all_nymd_mixnodes(&self) -> Result<Vec<MixNodeBond>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
@@ -475,8 +302,8 @@ impl<C> Client<C> {
pub async fn get_all_nymd_single_mixnode_delegations(
&self,
identity: IdentityKey,
) -> Result<Vec<Delegation>, ValidatorClientError>
identity: mixnet_contract_common::IdentityKey,
) -> Result<Vec<mixnet_contract_common::Delegation>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::cosmwasm_client::helpers::{create_pagination, next_page_key};
use crate::nymd::cosmwasm_client::helpers::create_pagination;
use crate::nymd::cosmwasm_client::types::{
Account, Code, CodeDetails, Contract, ContractCodeHistoryEntry, ContractCodeId,
SequenceResponse, SimulateResponse,
@@ -150,8 +150,8 @@ pub trait CosmWasmClient: rpc::Client {
.await?;
raw_balances.append(&mut res.balances);
if let Some(next_key) = next_page_key(res.pagination) {
pagination = Some(create_pagination(next_key))
if let Some(pagination_info) = res.pagination {
pagination = Some(create_pagination(pagination_info.next_key))
} else {
break;
}
@@ -182,8 +182,8 @@ pub trait CosmWasmClient: rpc::Client {
.await?;
supply.append(&mut res.supply);
if let Some(next_key) = next_page_key(res.pagination) {
pagination = Some(create_pagination(next_key))
if let Some(pagination_info) = res.pagination {
pagination = Some(create_pagination(pagination_info.next_key))
} else {
break;
}
@@ -274,8 +274,8 @@ pub trait CosmWasmClient: rpc::Client {
.await?;
raw_codes.append(&mut res.code_infos);
if let Some(next_key) = next_page_key(res.pagination) {
pagination = Some(create_pagination(next_key))
if let Some(pagination_info) = res.pagination {
pagination = Some(create_pagination(pagination_info.next_key))
} else {
break;
}
@@ -319,8 +319,8 @@ pub trait CosmWasmClient: rpc::Client {
.await?;
raw_contracts.append(&mut res.contracts);
if let Some(next_key) = next_page_key(res.pagination) {
pagination = Some(create_pagination(next_key))
if let Some(pagination_info) = res.pagination {
pagination = Some(create_pagination(pagination_info.next_key))
} else {
break;
}
@@ -375,8 +375,8 @@ pub trait CosmWasmClient: rpc::Client {
.await?;
raw_entries.append(&mut res.entries);
if let Some(next_key) = next_page_key(res.pagination) {
pagination = Some(create_pagination(next_key))
if let Some(pagination_info) = res.pagination {
pagination = Some(create_pagination(pagination_info.next_key))
} else {
break;
}
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::nymd::error::NymdError;
use cosmrs::proto::cosmos::base::query::v1beta1::{PageRequest, PageResponse};
use cosmrs::proto::cosmos::base::query::v1beta1::PageRequest;
use cosmrs::rpc::endpoint::broadcast;
use flate2::write::GzEncoder;
use flate2::Compression;
@@ -53,15 +53,3 @@ pub(crate) fn create_pagination(key: Vec<u8>) -> PageRequest {
count_total: false,
}
}
pub(crate) fn next_page_key(pagination_info: Option<PageResponse>) -> Option<Vec<u8>> {
if let Some(next_page_info) = pagination_info {
// it turns out, even though `PageResponse` is always returned wrapped in an `Option`,
// the `next_key` can still be empty, so check whether we actually need to perform another call
if !next_page_info.next_key.is_empty() {
return Some(next_page_info.next_key);
}
}
None
}
@@ -41,11 +41,6 @@ pub enum Operation {
WithdrawVestedCoins,
TrackUndelegation,
CreatePeriodicVestingAccount,
AdvanceCurrentInterval,
WriteRewardedSet,
ClearRewardedSet,
UpdateMixnetAddress,
}
pub(crate) fn calculate_fee(gas_price: &GasPrice, gas_limit: Gas) -> Coin {
@@ -83,10 +78,6 @@ impl fmt::Display for Operation {
Operation::WithdrawVestedCoins => f.write_str("WithdrawVestedCoins"),
Operation::TrackUndelegation => f.write_str("TrackUndelegation"),
Operation::CreatePeriodicVestingAccount => f.write_str("CreatePeriodicVestingAccount"),
Operation::AdvanceCurrentInterval => f.write_str("AdvanceCurrentInterval"),
Operation::WriteRewardedSet => f.write_str("WriteRewardedSet"),
Operation::ClearRewardedSet => f.write_str("ClearRewardedSet"),
Operation::UpdateMixnetAddress => f.write_str("UpdateMixnetAddress"),
}
}
}
@@ -124,10 +115,6 @@ impl Operation {
Operation::WithdrawVestedCoins => 175_000u64.into(),
Operation::TrackUndelegation => 175_000u64.into(),
Operation::CreatePeriodicVestingAccount => 175_000u64.into(),
Operation::AdvanceCurrentInterval => 175_000u64.into(),
Operation::WriteRewardedSet => 175_000u64.into(),
Operation::ClearRewardedSet => 175_000u64.into(),
Operation::UpdateMixnetAddress => 80_000u64.into(),
}
}
@@ -15,10 +15,10 @@ pub use fee::gas_price::GasPrice;
use fee::helpers::Operation;
use mixnet_contract_common::{
ContractStateParams, Delegation, ExecuteMsg, Gateway, GatewayBond, GatewayOwnershipResponse,
IdentityKey, Interval, LayerDistribution, MixNode, MixNodeBond, MixOwnershipResponse,
IdentityKey, LayerDistribution, MixNode, MixNodeBond, MixOwnershipResponse,
MixnetContractVersion, MixnodeRewardingStatusResponse, PagedAllDelegationsResponse,
PagedDelegatorDelegationsResponse, PagedGatewayResponse, PagedMixDelegationsResponse,
PagedMixnodeResponse, PagedRewardedSetResponse, QueryMsg, RewardedSetUpdateDetails,
PagedMixnodeResponse, QueryMsg, RewardingIntervalResponse,
};
use serde::Serialize;
use std::convert::TryInto;
@@ -27,12 +27,9 @@ pub use crate::nymd::cosmwasm_client::client::CosmWasmClient;
pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient;
pub use crate::nymd::fee::Fee;
use crate::nymd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER;
pub use cosmrs::rpc::endpoint::validators::Response as ValidatorResponse;
pub use cosmrs::rpc::HttpClient as QueryNymdClient;
pub use cosmrs::rpc::Paging;
pub use cosmrs::tendermint::block::Height;
pub use cosmrs::tendermint::hash;
pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo;
pub use cosmrs::tendermint::Time as TendermintTime;
pub use cosmrs::tx::{self, Gas};
pub use cosmrs::Coin as CosmosCoin;
@@ -52,7 +49,6 @@ pub struct NymdClient<C> {
client: C,
mixnet_contract_address: Option<AccountId>,
vesting_contract_address: Option<AccountId>,
erc20_bridge_contract_address: Option<AccountId>,
client_address: Option<Vec<AccountId>>,
custom_gas_limits: HashMap<Operation, Gas>,
simulated_gas_multiplier: f32,
@@ -63,7 +59,6 @@ impl NymdClient<QueryNymdClient> {
endpoint: U,
mixnet_contract_address: Option<AccountId>,
vesting_contract_address: Option<AccountId>,
erc20_bridge_contract_address: Option<AccountId>,
) -> Result<NymdClient<QueryNymdClient>, NymdError>
where
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
@@ -72,7 +67,6 @@ impl NymdClient<QueryNymdClient> {
client: QueryNymdClient::new(endpoint)?,
mixnet_contract_address,
vesting_contract_address,
erc20_bridge_contract_address,
client_address: None,
custom_gas_limits: Default::default(),
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
@@ -86,7 +80,6 @@ impl NymdClient<SigningNymdClient> {
endpoint: U,
mixnet_contract_address: Option<AccountId>,
vesting_contract_address: Option<AccountId>,
erc20_bridge_contract_address: Option<AccountId>,
signer: DirectSecp256k1HdWallet,
gas_price: Option<GasPrice>,
) -> Result<NymdClient<SigningNymdClient>, NymdError>
@@ -103,7 +96,6 @@ impl NymdClient<SigningNymdClient> {
client: SigningNymdClient::connect_with_signer(endpoint, signer, gas_price)?,
mixnet_contract_address,
vesting_contract_address,
erc20_bridge_contract_address,
client_address: Some(client_address),
custom_gas_limits: Default::default(),
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
@@ -111,19 +103,16 @@ impl NymdClient<SigningNymdClient> {
}
pub fn connect_with_mnemonic<U>(
network: config::defaults::all::Network,
endpoint: U,
mixnet_contract_address: Option<AccountId>,
vesting_contract_address: Option<AccountId>,
erc20_bridge_contract_address: Option<AccountId>,
mnemonic: bip39::Mnemonic,
gas_price: Option<GasPrice>,
) -> Result<NymdClient<SigningNymdClient>, NymdError>
where
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
{
let prefix = network.bech32_prefix();
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic)?;
let wallet = DirectSecp256k1HdWallet::from_mnemonic(mnemonic)?;
let client_address = wallet
.try_derive_accounts()?
.into_iter()
@@ -134,7 +123,6 @@ impl NymdClient<SigningNymdClient> {
client: SigningNymdClient::connect_with_signer(endpoint, wallet, gas_price)?,
mixnet_contract_address,
vesting_contract_address,
erc20_bridge_contract_address,
client_address: Some(client_address),
custom_gas_limits: Default::default(),
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
@@ -155,12 +143,6 @@ impl<C> NymdClient<C> {
.ok_or(NymdError::NoContractAddressAvailable)
}
pub fn erc20_bridge_contract_address(&self) -> Result<&AccountId, NymdError> {
self.erc20_bridge_contract_address
.as_ref()
.ok_or(NymdError::NoContractAddressAvailable)
}
// now the question is as follows: will denom always be in the format of `u{prefix}`?
pub fn denom(&self) -> Result<Denom, NymdError> {
Ok(format!("u{}", self.mixnet_contract_address()?.prefix())
@@ -252,17 +234,6 @@ impl<C> NymdClient<C> {
.map(|block| block.block_id.hash)
}
pub async fn get_validators(
&self,
height: u64,
paging: Paging,
) -> Result<ValidatorResponse, NymdError>
where
C: CosmWasmClient + Sync,
{
Ok(self.client.validators(height as u32, paging).await?)
}
pub async fn get_balance(
&self,
address: &AccountId,
@@ -274,6 +245,16 @@ impl<C> NymdClient<C> {
self.client.get_balance(address, denom).await
}
pub async fn get_mixnet_balance(
&self,
address: &AccountId,
) -> Result<Option<CosmosCoin>, NymdError>
where
C: CosmWasmClient + Sync,
{
self.get_balance(address, self.denom()?).await
}
pub async fn get_total_supply(&self) -> Result<Vec<Coin>, NymdError>
where
C: CosmWasmClient + Sync,
@@ -301,65 +282,35 @@ impl<C> NymdClient<C> {
.await
}
pub async fn get_current_rewarding_interval(
&self,
) -> Result<RewardingIntervalResponse, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::CurrentRewardingInterval {};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
}
pub async fn get_rewarding_status(
&self,
mix_identity: mixnet_contract_common::IdentityKey,
interval_id: u32,
rewarding_interval_nonce: u32,
) -> Result<MixnodeRewardingStatusResponse, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::GetRewardingStatus {
mix_identity,
interval_id,
rewarding_interval_nonce,
};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
}
pub async fn query_current_rewarded_set_height(&self) -> Result<u64, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::GetCurrentRewardedSetHeight {};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
}
pub async fn query_current_rewarded_set_update_details(
&self,
) -> Result<RewardedSetUpdateDetails, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::GetRewardedSetUpdateDetails {};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
}
pub async fn get_rewarded_set_identities_paged(
&self,
start_after: Option<IdentityKey>,
page_limit: Option<u32>,
height: Option<u64>,
) -> Result<PagedRewardedSetResponse, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::GetRewardedSet {
height,
start_after,
limit: page_limit,
};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
}
pub async fn get_layer_distribution(&self) -> Result<LayerDistribution, NymdError>
where
C: CosmWasmClient + Sync,
@@ -370,16 +321,6 @@ impl<C> NymdClient<C> {
.await
}
pub async fn get_current_interval(&self) -> Result<Interval, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::GetCurrentInterval {};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
}
pub async fn get_reward_pool(&self) -> Result<Uint128, NymdError>
where
C: CosmWasmClient + Sync,
@@ -410,21 +351,11 @@ impl<C> NymdClient<C> {
.await
}
pub async fn get_active_set_work_factor(&self) -> Result<u8, NymdError>
pub async fn get_epoch_reward_percent(&self) -> Result<u8, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::GetActiveSetWorkFactor {};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
}
pub async fn get_interval_reward_percent(&self) -> Result<u8, NymdError>
where
C: CosmWasmClient + Sync,
{
let request = QueryMsg::GetIntervalRewardPercent {};
let request = QueryMsg::GetEpochRewardPercent {};
self.client
.query_contract_smart(self.mixnet_contract_address()?, &request)
.await
@@ -1177,38 +1108,17 @@ impl<C> NymdClient<C> {
.await
}
pub async fn advance_current_interval(&self) -> Result<ExecuteResult, NymdError>
where
C: SigningCosmWasmClient + Sync,
{
let fee = self.operation_fee(Operation::AdvanceCurrentInterval);
let req = ExecuteMsg::AdvanceCurrentInterval {};
self.client
.execute(
self.address(),
self.mixnet_contract_address()?,
&req,
fee,
"Advancing current interval",
Vec::new(),
)
.await
}
pub async fn write_rewarded_set(
pub async fn begin_mixnode_rewarding(
&self,
rewarded_set: Vec<IdentityKey>,
expected_active_set_size: u32,
rewarding_interval_nonce: u32,
) -> Result<ExecuteResult, NymdError>
where
C: SigningCosmWasmClient + Sync,
{
let fee = self.operation_fee(Operation::WriteRewardedSet);
let fee = self.operation_fee(Operation::BeginMixnodeRewarding);
let req = ExecuteMsg::WriteRewardedSet {
rewarded_set,
expected_active_set_size,
let req = ExecuteMsg::BeginMixnodeRewarding {
rewarding_interval_nonce,
};
self.client
.execute(
@@ -1216,7 +1126,31 @@ impl<C> NymdClient<C> {
self.mixnet_contract_address()?,
&req,
fee,
"Writing rewarded set",
"Beginning mixnode rewarding procedure",
Vec::new(),
)
.await
}
pub async fn finish_mixnode_rewarding(
&self,
rewarding_interval_nonce: u32,
) -> Result<ExecuteResult, NymdError>
where
C: SigningCosmWasmClient + Sync,
{
let fee = self.operation_fee(Operation::FinishMixnodeRewarding);
let req = ExecuteMsg::FinishMixnodeRewarding {
rewarding_interval_nonce,
};
self.client
.execute(
self.address(),
self.mixnet_contract_address()?,
&req,
fee,
"Finishing mixnode rewarding procedure",
Vec::new(),
)
.await
@@ -6,10 +6,7 @@ use crate::nymd::error::NymdError;
use crate::nymd::NymdClient;
use async_trait::async_trait;
use cosmwasm_std::{Coin, Timestamp};
use vesting_contract::vesting::Account;
use vesting_contract_common::{
messages::QueryMsg as VestingQueryMsg, OriginalVestingResponse, Period, PledgeData,
};
use vesting_contract::messages::QueryMsg as VestingQueryMsg;
#[async_trait]
pub trait VestingQueryClient {
@@ -45,10 +42,7 @@ pub trait VestingQueryClient {
async fn vesting_end_time(&self, vesting_account_address: &str)
-> Result<Timestamp, NymdError>;
async fn original_vesting(
&self,
vesting_account_address: &str,
) -> Result<OriginalVestingResponse, NymdError>;
async fn original_vesting(&self, vesting_account_address: &str) -> Result<Coin, NymdError>;
async fn delegated_free(
&self,
@@ -61,14 +55,6 @@ pub trait VestingQueryClient {
vesting_account_address: &str,
block_time: Option<Timestamp>,
) -> Result<Coin, NymdError>;
async fn get_account(&self, address: &str) -> Result<Account, NymdError>;
async fn get_mixnode_pledge(&self, address: &str) -> Result<Option<PledgeData>, NymdError>;
async fn get_gateway_pledge(&self, address: &str) -> Result<Option<PledgeData>, NymdError>;
async fn get_current_vesting_period(
&self,
vesting_account_address: &str,
) -> Result<Period, NymdError>;
}
#[async_trait]
@@ -151,10 +137,7 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
.await
}
async fn original_vesting(
&self,
vesting_account_address: &str,
) -> Result<OriginalVestingResponse, NymdError> {
async fn original_vesting(&self, vesting_account_address: &str) -> Result<Coin, NymdError> {
let request = VestingQueryMsg::GetOriginalVesting {
vesting_account_address: vesting_account_address.to_string(),
};
@@ -190,38 +173,4 @@ impl<C: CosmWasmClient + Sync + Send> VestingQueryClient for NymdClient<C> {
.query_contract_smart(self.vesting_contract_address()?, &request)
.await
}
async fn get_account(&self, address: &str) -> Result<Account, NymdError> {
let request = VestingQueryMsg::GetAccount {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.await
}
async fn get_mixnode_pledge(&self, address: &str) -> Result<Option<PledgeData>, NymdError> {
let request = VestingQueryMsg::GetMixnode {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.await
}
async fn get_gateway_pledge(&self, address: &str) -> Result<Option<PledgeData>, NymdError> {
let request = VestingQueryMsg::GetGateway {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.await
}
async fn get_current_vesting_period(&self, address: &str) -> Result<Period, NymdError> {
let request = VestingQueryMsg::GetCurrentVestingPeriod {
address: address.to_string(),
};
self.client
.query_contract_smart(self.vesting_contract_address()?, &request)
.await
}
}
@@ -9,17 +9,10 @@ use crate::nymd::{cosmwasm_coin_to_cosmos_coin, NymdClient};
use async_trait::async_trait;
use cosmwasm_std::Coin;
use mixnet_contract_common::{Gateway, IdentityKey, IdentityKeyRef, MixNode};
use vesting_contract_common::messages::{ExecuteMsg as VestingExecuteMsg, VestingSpecification};
use vesting_contract::messages::ExecuteMsg as VestingExecuteMsg;
#[async_trait]
pub trait VestingSigningClient {
async fn vesting_update_mixnode_config(
&self,
profix_margin_percent: u8,
) -> Result<ExecuteResult, NymdError>;
async fn update_mixnet_address(&self, address: &str) -> Result<ExecuteResult, NymdError>;
async fn vesting_bond_gateway(
&self,
gateway: Gateway,
@@ -73,7 +66,7 @@ pub trait VestingSigningClient {
&self,
owner_address: &str,
staking_address: Option<String>,
vesting_spec: Option<VestingSpecification>,
start_time: Option<u64>,
amount: Coin,
) -> Result<ExecuteResult, NymdError>;
}
@@ -90,7 +83,6 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
let req = VestingExecuteMsg::BondGateway {
gateway,
owner_signature: owner_signature.to_string(),
amount: pledge,
};
self.client
.execute(
@@ -99,7 +91,7 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
&req,
fee,
"VestingContract::BondGateway",
vec![],
vec![cosmwasm_coin_to_cosmos_coin(pledge)],
)
.await
}
@@ -151,7 +143,6 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
let req = VestingExecuteMsg::BondMixnode {
mix_node,
owner_signature: owner_signature.to_string(),
amount: pledge,
};
self.client
.execute(
@@ -160,7 +151,7 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
&req,
fee,
"VestingContract::BondMixnode",
vec![],
vec![cosmwasm_coin_to_cosmos_coin(pledge)],
)
.await
}
@@ -248,7 +239,6 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
let fee = self.operation_fee(Operation::DelegateToMixnode);
let req = VestingExecuteMsg::DelegateToMixnode {
mix_identity: mix_identity.into(),
amount: amount.clone(),
};
self.client
.execute(
@@ -257,7 +247,7 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
&req,
fee,
"VestingContract::DeledateToMixnode",
vec![],
vec![cosmwasm_coin_to_cosmos_coin(amount.to_owned())],
)
.await
}
@@ -284,14 +274,14 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
&self,
owner_address: &str,
staking_address: Option<String>,
vesting_spec: Option<VestingSpecification>,
start_time: Option<u64>,
amount: Coin,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::CreatePeriodicVestingAccount);
let req = VestingExecuteMsg::CreateAccount {
owner_address: owner_address.to_string(),
staking_address,
vesting_spec,
start_time,
};
self.client
.execute(
@@ -304,41 +294,4 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
)
.await
}
async fn update_mixnet_address(&self, address: &str) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::UpdateMixnetAddress);
let req = VestingExecuteMsg::UpdateMixnetAddress {
address: address.to_string(),
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
&req,
fee,
"VestingContract::UpdateMixnetAddress",
vec![],
)
.await
}
async fn vesting_update_mixnode_config(
&self,
profit_margin_percent: u8,
) -> Result<ExecuteResult, NymdError> {
let fee = self.operation_fee(Operation::UpdateMixnodeConfig);
let req = VestingExecuteMsg::UpdateMixnodeConfig {
profit_margin_percent,
};
self.client
.execute(
self.address(),
self.vesting_contract_address()?,
&req,
fee,
"VestingContract::UpdateMixnetConfig",
vec![],
)
.await
}
}
@@ -62,15 +62,13 @@ impl DirectSecp256k1HdWallet {
}
/// Restores a wallet from the given BIP39 mnemonic using default options.
pub fn from_mnemonic(prefix: String, mnemonic: bip39::Mnemonic) -> Result<Self, NymdError> {
DirectSecp256k1HdWalletBuilder::new()
.with_prefix(prefix)
.build(mnemonic)
pub fn from_mnemonic(mnemonic: bip39::Mnemonic) -> Result<Self, NymdError> {
DirectSecp256k1HdWalletBuilder::new().build(mnemonic)
}
pub fn generate(prefix: String, word_count: usize) -> Result<Self, NymdError> {
pub fn generate(word_count: usize) -> Result<Self, NymdError> {
let mneomonic = bip39::Mnemonic::generate(word_count)?;
Self::from_mnemonic(prefix, mneomonic)
Self::from_mnemonic(mneomonic)
}
fn derive_keypair(&self, hd_path: &DerivationPath) -> Result<Secp256k1Keypair, NymdError> {
@@ -205,7 +203,7 @@ impl DirectSecp256k1HdWalletBuilder {
#[cfg(test)]
mod tests {
use super::*;
use network_defaults::{default_network, BECH32_PREFIX};
use network_defaults::BECH32_PREFIX;
#[test]
fn generating_account_addresses() {
@@ -230,9 +228,7 @@ mod tests {
];
for (mnemonic, address) in mnemonic_address.into_iter() {
let prefix = default_network().bech32_prefix();
let wallet =
DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic.parse().unwrap()).unwrap();
let wallet = DirectSecp256k1HdWallet::from_mnemonic(mnemonic.parse().unwrap()).unwrap();
assert_eq!(
wallet.try_derive_accounts().unwrap()[0].address,
address.parse().unwrap()
@@ -9,8 +9,8 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use url::Url;
use validator_api_requests::models::{
CoreNodeStatusResponse, InclusionProbabilityResponse, MixnodeStatusResponse,
RewardEstimationResponse, StakeSaturationResponse,
CoreNodeStatusResponse, MixnodeStatusResponse, RewardEstimationResponse,
StakeSaturationResponse,
};
pub mod error;
@@ -232,23 +232,6 @@ impl Client {
.await
}
pub async fn get_mixnode_inclusion_probability(
&self,
identity: IdentityKeyRef<'_>,
) -> Result<InclusionProbabilityResponse, ValidatorAPIError> {
self.query_validator_api(
&[
routes::API_VERSION,
routes::STATUS_ROUTES,
routes::MIXNODE,
identity,
routes::INCLUSION_CHANCE,
],
NO_PARAMS,
)
.await
}
pub async fn blind_sign(
&self,
request_body: &BlindSignRequestBody,
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "coconut-interface"
version = "0.1.0"
edition = "2021"
edition = "2018"
description = "Crutch library until there is proper SerDe support for coconut structs"
[dependencies]
+1 -1
View File
@@ -2,7 +2,7 @@
name = "config"
version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -2,7 +2,7 @@
name = "mixnet-contract-common"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -12,20 +12,14 @@ cosmwasm-std = "1.0.0-beta3"
serde = { version = "1.0", features = ["derive"] }
serde_repr = "0.1"
schemars = "0.8"
# Leaving it as * so that it inherits whatever the wallet is using
ts-rs = { version = "*", optional = true }
ts-rs = { version = "5.1", optional = true }
thiserror = "1.0"
network-defaults = { path = "../../network-defaults" }
fixed = { version = "1.1", features = ["serde"] }
az = "1.1"
log = "0.4.14"
time = { version = "0.3.6", features = ["parsing", "formatting"] }
contracts-common = { path = "../contracts-common" }
[dev-dependencies]
time = { version = "0.3.5", features = ["serde", "macros"] }
[features]
default = []
@@ -66,7 +66,7 @@ impl Delegation {
}
impl Display for Delegation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"{} delegated towards {} by {} at block {}",
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::mixnode::NodeRewardResult;
use crate::{ContractStateParams, Delegation, IdentityKeyRef, Interval, Layer};
use crate::{ContractStateParams, Delegation, IdentityKeyRef, Layer};
use cosmwasm_std::{Addr, Coin, Event, Uint128};
pub use contracts_common::events::*;
@@ -15,10 +15,10 @@ pub const GATEWAY_UNBONDING_EVENT_TYPE: &str = "gateway_unbonding";
pub const MIXNODE_BONDING_EVENT_TYPE: &str = "mixnode_bonding";
pub const MIXNODE_UNBONDING_EVENT_TYPE: &str = "mixnode_unbonding";
pub const SETTINGS_UPDATE_EVENT_TYPE: &str = "settings_update";
pub const BEGIN_REWARDING_EVENT_TYPE: &str = "begin_rewarding";
pub const OPERATOR_REWARDING_EVENT_TYPE: &str = "mix_rewarding";
pub const MIX_DELEGATORS_REWARDING_EVENT_TYPE: &str = "mix_delegators_rewarding";
pub const CHANGE_REWARDED_SET_EVENT_TYPE: &str = "change_rewarded_set";
pub const ADVANCE_INTERVAL_EVENT_TYPE: &str = "advance_interval";
pub const FINISH_REWARDING_EVENT_TYPE: &str = "finish_rewarding";
// attributes that are used in multiple places
pub const OWNER_KEY: &str = "owner";
@@ -47,13 +47,12 @@ pub const NEW_MINIMUM_MIXNODE_PLEDGE_KEY: &str = "new_minimum_mixnode_pledge";
pub const NEW_MINIMUM_GATEWAY_PLEDGE_KEY: &str = "new_minimum_gateway_pledge";
pub const NEW_MIXNODE_REWARDED_SET_SIZE_KEY: &str = "new_mixnode_rewarded_set_size";
pub const NEW_MIXNODE_ACTIVE_SET_SIZE_KEY: &str = "new_mixnode_active_set_size";
pub const NEW_ACTIVE_SET_WORK_FACTOR_KEY: &str = "new_active_set_work_factor";
// rewarding
pub const INTERVAL_ID_KEY: &str = "interval_id";
pub const REWARDING_INTERVAL_NONCE_KEY: &str = "rewarding_interval_nonce";
pub const TOTAL_MIXNODE_REWARD_KEY: &str = "total_node_reward";
pub const OPERATOR_REWARD_KEY: &str = "operator_reward";
pub const TOTAL_PLEDGE_KEY: &str = "pledge";
pub const TOTAL_DELEGATIONS_KEY: &str = "delegated";
pub const LAMBDA_KEY: &str = "lambda";
pub const SIGMA_KEY: &str = "sigma";
pub const DISTRIBUTED_DELEGATION_REWARDS_KEY: &str = "distributed_delegation_rewards";
@@ -63,19 +62,11 @@ pub const BOND_NOT_FOUND_VALUE: &str = "bond_not_found";
pub const BOND_TOO_FRESH_VALUE: &str = "bond_too_fresh";
pub const ZERO_UPTIME_VALUE: &str = "zero_uptime";
// rewarded set update
pub const ACTIVE_SET_SIZE_KEY: &str = "active_set_size";
pub const REWARDED_SET_SIZE_KEY: &str = "rewarded_set_size";
pub const NODES_IN_REWARDED_SET_KEY: &str = "nodes_in_rewarded_set";
pub const CURRENT_INTERVAL_ID_KEY: &str = "current_interval";
pub const NEW_CURRENT_INTERVAL_KEY: &str = "new_current_interval";
pub fn new_delegation_event(
delegator: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
mix_identity: IdentityKeyRef<'_>,
mix_identity: IdentityKeyRef,
) -> Event {
let mut event = Event::new(DELEGATION_EVENT_TYPE).add_attribute(DELEGATOR_KEY, delegator);
@@ -93,7 +84,7 @@ pub fn new_undelegation_event(
delegator: &Addr,
proxy: &Option<Addr>,
old_delegation: &Delegation,
mix_identity: IdentityKeyRef<'_>,
mix_identity: IdentityKeyRef,
) -> Event {
let mut event = Event::new(UNDELEGATION_EVENT_TYPE).add_attribute(DELEGATOR_KEY, delegator);
@@ -115,7 +106,7 @@ pub fn new_gateway_bonding_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
identity: IdentityKeyRef<'_>,
identity: IdentityKeyRef,
) -> Event {
let mut event = Event::new(GATEWAY_BONDING_EVENT_TYPE)
.add_attribute(OWNER_KEY, owner)
@@ -133,7 +124,7 @@ pub fn new_gateway_unbonding_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
identity: IdentityKeyRef<'_>,
identity: IdentityKeyRef,
) -> Event {
let mut event = Event::new(GATEWAY_UNBONDING_EVENT_TYPE)
.add_attribute(OWNER_KEY, owner)
@@ -151,7 +142,7 @@ pub fn new_mixnode_bonding_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
identity: IdentityKeyRef<'_>,
identity: IdentityKeyRef,
assigned_layer: Layer,
) -> Event {
let mut event = Event::new(MIXNODE_BONDING_EVENT_TYPE)
@@ -172,7 +163,7 @@ pub fn new_mixnode_unbonding_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
identity: IdentityKeyRef<'_>,
identity: IdentityKeyRef,
) -> Event {
let mut event = Event::new(MIXNODE_UNBONDING_EVENT_TYPE)
.add_attribute(OWNER_KEY, owner)
@@ -240,55 +231,88 @@ pub fn new_settings_update_event(
)
}
if old_params.active_set_work_factor != new_params.active_set_work_factor {
event = event
.add_attribute(
OLD_ACTIVE_SET_WORK_FACTOR_KEY,
old_params.active_set_work_factor.to_string(),
)
.add_attribute(
NEW_ACTIVE_SET_WORK_FACTOR_KEY,
new_params.active_set_work_factor.to_string(),
)
}
event
}
pub fn new_begin_rewarding_event(rewarding_interval_nonce: u32) -> Event {
Event::new(BEGIN_REWARDING_EVENT_TYPE).add_attribute(
REWARDING_INTERVAL_NONCE_KEY,
rewarding_interval_nonce.to_string(),
)
}
pub fn new_finish_rewarding_event(rewarding_interval_nonce: u32) -> Event {
Event::new(FINISH_REWARDING_EVENT_TYPE).add_attribute(
REWARDING_INTERVAL_NONCE_KEY,
rewarding_interval_nonce.to_string(),
)
}
pub fn new_not_found_mix_operator_rewarding_event(
interval_id: u32,
identity: IdentityKeyRef<'_>,
rewarding_interval_nonce: u32,
identity: IdentityKeyRef,
) -> Event {
Event::new(OPERATOR_REWARDING_EVENT_TYPE)
.add_attribute(INTERVAL_ID_KEY, interval_id.to_string())
.add_attribute(
REWARDING_INTERVAL_NONCE_KEY,
rewarding_interval_nonce.to_string(),
)
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_attribute(NO_REWARD_REASON_KEY, BOND_NOT_FOUND_VALUE)
}
pub fn new_too_fresh_bond_mix_operator_rewarding_event(
interval_id: u32,
identity: IdentityKeyRef<'_>,
rewarding_interval_nonce: u32,
identity: IdentityKeyRef,
) -> Event {
Event::new(OPERATOR_REWARDING_EVENT_TYPE)
.add_attribute(INTERVAL_ID_KEY, interval_id.to_string())
.add_attribute(
REWARDING_INTERVAL_NONCE_KEY,
rewarding_interval_nonce.to_string(),
)
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_attribute(NO_REWARD_REASON_KEY, BOND_TOO_FRESH_VALUE)
}
pub fn new_zero_uptime_mix_operator_rewarding_event(
interval_id: u32,
identity: IdentityKeyRef<'_>,
rewarding_interval_nonce: u32,
identity: IdentityKeyRef,
) -> Event {
Event::new(OPERATOR_REWARDING_EVENT_TYPE)
.add_attribute(INTERVAL_ID_KEY, interval_id.to_string())
.add_attribute(
REWARDING_INTERVAL_NONCE_KEY,
rewarding_interval_nonce.to_string(),
)
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_attribute(NO_REWARD_REASON_KEY, ZERO_UPTIME_VALUE)
}
#[allow(clippy::too_many_arguments)]
pub fn new_mix_operator_rewarding_event(
interval_id: u32,
identity: IdentityKeyRef<'_>,
rewarding_interval_nonce: u32,
identity: IdentityKeyRef,
node_reward_result: NodeRewardResult,
node_pledge: Uint128,
node_delegation: Uint128,
operator_reward: Uint128,
delegation_rewards_distributed: Uint128,
further_delegations: bool,
) -> Event {
Event::new(OPERATOR_REWARDING_EVENT_TYPE)
.add_attribute(INTERVAL_ID_KEY, interval_id.to_string())
.add_attribute(
REWARDING_INTERVAL_NONCE_KEY,
rewarding_interval_nonce.to_string(),
)
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_attribute(TOTAL_PLEDGE_KEY, node_pledge)
.add_attribute(TOTAL_DELEGATIONS_KEY, node_delegation)
.add_attribute(
TOTAL_MIXNODE_REWARD_KEY,
node_reward_result.reward().to_string(),
@@ -307,13 +331,16 @@ pub fn new_mix_operator_rewarding_event(
}
pub fn new_mix_delegators_rewarding_event(
interval_id: u32,
identity: IdentityKeyRef<'_>,
rewarding_interval_nonce: u32,
identity: IdentityKeyRef,
delegation_rewards_distributed: Uint128,
further_delegations: bool,
) -> Event {
Event::new(MIX_DELEGATORS_REWARDING_EVENT_TYPE)
.add_attribute(INTERVAL_ID_KEY, interval_id.to_string())
.add_attribute(
REWARDING_INTERVAL_NONCE_KEY,
rewarding_interval_nonce.to_string(),
)
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_attribute(
DISTRIBUTED_DELEGATION_REWARDS_KEY,
@@ -324,22 +351,3 @@ pub fn new_mix_delegators_rewarding_event(
further_delegations.to_string(),
)
}
// note that when this event is emitted, we'll know the current block height
pub fn new_change_rewarded_set_event(
active_set_size: u32,
rewarded_set_size: u32,
nodes_in_rewarded_set: u32,
current_interval_id: u32,
) -> Event {
Event::new(CHANGE_REWARDED_SET_EVENT_TYPE)
.add_attribute(ACTIVE_SET_SIZE_KEY, active_set_size.to_string())
.add_attribute(REWARDED_SET_SIZE_KEY, rewarded_set_size.to_string())
.add_attribute(NODES_IN_REWARDED_SET_KEY, nodes_in_rewarded_set.to_string())
.add_attribute(CURRENT_INTERVAL_ID_KEY, current_interval_id.to_string())
}
pub fn new_advance_interval_event(interval: Interval) -> Event {
Event::new(ADVANCE_INTERVAL_EVENT_TYPE)
.add_attribute(NEW_CURRENT_INTERVAL_KEY, interval.to_string())
}
@@ -98,7 +98,7 @@ impl PartialOrd for GatewayBond {
}
impl Display for GatewayBond {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"amount: {} {}, owner: {}, identity: {}",
@@ -1,365 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::fmt::{Display, Formatter};
use std::time::Duration;
use time::OffsetDateTime;
// internally, since version 0.3.6, time uses deserialize_any for deserialization, which can't be handled
// by serde wasm. We could just downgrade to 0.3.5 and call it a day, but then it would break
// when we decided to upgrade it at some point in the future. And then it would have been more problematic
// to fix it, since the data would have already been stored inside the contract.
// Hence, an explicit workaround to use string representation of Rfc3339-formatted datetime.
pub(crate) mod string_rfc3339_offset_date_time {
use serde::de::Visitor;
use serde::ser::Error;
use serde::{Deserializer, Serialize, Serializer};
use std::fmt::Formatter;
use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;
struct Rfc3339OffsetDateTimeVisitor;
impl<'de> Visitor<'de> for Rfc3339OffsetDateTimeVisitor {
type Value = OffsetDateTime;
fn expecting(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str("an rfc3339 `OffsetDateTime`")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
OffsetDateTime::parse(value, &Rfc3339).map_err(E::custom)
}
}
pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(Rfc3339OffsetDateTimeVisitor)
}
pub(crate) fn serialize<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
datetime
.format(&Rfc3339)
.map_err(S::Error::custom)?
.serialize(serializer)
}
}
/// Representation of rewarding interval.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct Interval {
id: u32,
#[serde(with = "string_rfc3339_offset_date_time")]
start: OffsetDateTime,
length: Duration,
}
impl Interval {
/// Creates new interval instance.
pub const fn new(id: u32, start: OffsetDateTime, length: Duration) -> Self {
Interval { id, start, length }
}
/// Returns the next interval.
#[must_use]
pub fn next_interval(&self) -> Self {
Interval {
id: self.id + 1,
start: self.end(),
length: self.length,
}
}
/// Returns the last interval.
pub fn previous_interval(&self) -> Option<Self> {
if self.id > 0 {
Some(Interval {
id: self.id - 1,
start: self.start - self.length,
length: self.length,
})
} else {
None
}
}
/// Determines whether the provided datetime is contained within the interval
///
/// # Arguments
///
/// * `datetime`: specified datetime
pub fn contains(&self, datetime: OffsetDateTime) -> bool {
self.start <= datetime && datetime <= self.end()
}
/// Determines whether the provided unix timestamp is contained within the interval
///
/// # Arguments
///
/// * `timestamp`: specified timestamp
pub fn contains_timestamp(&self, timestamp: i64) -> bool {
self.start_unix_timestamp() <= timestamp && timestamp <= self.end_unix_timestamp()
}
/// Returns new instance of [Interval] such that the provided datetime would be within
/// its duration.
///
/// # Arguments
///
/// * `now`: current datetime
pub fn current(&self, now: OffsetDateTime) -> Option<Self> {
let mut candidate = *self;
if now > self.start {
loop {
if candidate.contains(now) {
return Some(candidate);
}
candidate = candidate.next_interval();
}
} else {
loop {
if candidate.contains(now) {
return Some(candidate);
}
candidate = candidate.previous_interval()?;
}
}
}
/// Returns new instance of [Interval] such that the provided unix timestamp would be within
/// its duration.
///
/// # Arguments
///
/// * `now_unix`: current unix time
pub fn current_with_timestamp(&self, now_unix: i64) -> Option<Self> {
let mut candidate = *self;
if now_unix > self.start_unix_timestamp() {
loop {
if candidate.contains_timestamp(now_unix) {
return Some(candidate);
}
candidate = candidate.next_interval();
}
} else {
loop {
if candidate.contains_timestamp(now_unix) {
return Some(candidate);
}
candidate = candidate.previous_interval()?;
}
}
}
/// Checks whether this interval has already finished
///
/// # Arguments
///
/// * `now`: current datetime
pub fn has_elapsed(&self, now: OffsetDateTime) -> bool {
self.end() < now
}
/// Returns id of this interval
pub const fn id(&self) -> u32 {
self.id
}
/// Determines amount of time left until this interval finishes.
///
/// # Arguments
///
/// * `now`: current datetime
pub fn until_end(&self, now: OffsetDateTime) -> Option<Duration> {
let remaining = self.end() - now;
if remaining.is_negative() {
None
} else {
remaining.try_into().ok()
}
}
/// Returns the starting datetime of this interval.
pub const fn start(&self) -> OffsetDateTime {
self.start
}
/// Returns the length of this interval.
pub const fn length(&self) -> Duration {
self.length
}
/// Returns the ending datetime of this interval.
pub fn end(&self) -> OffsetDateTime {
self.start + self.length
}
/// Returns the unix timestamp of the start of this interval.
pub const fn start_unix_timestamp(&self) -> i64 {
self.start().unix_timestamp()
}
/// Returns the unix timestamp of the end of this interval.
pub fn end_unix_timestamp(&self) -> i64 {
self.end().unix_timestamp()
}
}
impl Display for Interval {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let length = self.length().as_secs();
let full_hours = length / 3600;
let rem = length % 3600;
write!(
f,
"Interval {}: {} - {} ({}h {}s)",
self.id,
self.start(),
self.end(),
full_hours,
rem
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn previous_interval() {
let interval = Interval {
id: 1,
start: time::macros::datetime!(2021-08-23 12:00 UTC),
length: Duration::from_secs(24 * 60 * 60),
};
let expected = Interval {
id: 0,
start: time::macros::datetime!(2021-08-22 12:00 UTC),
length: Duration::from_secs(24 * 60 * 60),
};
assert_eq!(expected, interval.previous_interval().unwrap());
let genesis_interval = Interval {
id: 0,
start: time::macros::datetime!(2021-08-23 12:00 UTC),
length: Duration::from_secs(24 * 60 * 60),
};
assert!(genesis_interval.previous_interval().is_none());
}
#[test]
fn next_interval() {
let interval = Interval {
id: 0,
start: time::macros::datetime!(2021-08-23 12:00 UTC),
length: Duration::from_secs(24 * 60 * 60),
};
let expected = Interval {
id: 1,
start: time::macros::datetime!(2021-08-24 12:00 UTC),
length: Duration::from_secs(24 * 60 * 60),
};
assert_eq!(expected, interval.next_interval())
}
#[test]
fn checking_for_datetime_inclusion() {
let interval = Interval {
id: 100,
start: time::macros::datetime!(2021-08-23 12:00 UTC),
length: Duration::from_secs(24 * 60 * 60),
};
// it must contain its own boundaries
assert!(interval.contains(interval.start));
assert!(interval.contains(interval.end()));
let in_the_midle = interval.start + Duration::from_secs(interval.length.as_secs() / 2);
assert!(interval.contains(in_the_midle));
assert!(!interval.contains(interval.next_interval().end()));
assert!(!interval.contains(interval.previous_interval().unwrap().start()));
}
#[test]
fn determining_current_interval() {
let first_interval = Interval {
id: 100,
start: time::macros::datetime!(2021-08-23 12:00 UTC),
length: Duration::from_secs(24 * 60 * 60),
};
// interval just before
let fake_now = first_interval.start - Duration::from_secs(123);
assert_eq!(
first_interval.previous_interval(),
first_interval.current(fake_now)
);
// this interval (start boundary)
assert_eq!(
first_interval,
first_interval.current(first_interval.start).unwrap()
);
// this interval (in the middle)
let fake_now = first_interval.start + Duration::from_secs(123);
assert_eq!(first_interval, first_interval.current(fake_now).unwrap());
// this interval (end boundary)
assert_eq!(
first_interval,
first_interval.current(first_interval.end()).unwrap()
);
// next interval
let fake_now = first_interval.end() + Duration::from_secs(123);
assert_eq!(
first_interval.next_interval(),
first_interval.current(fake_now).unwrap()
);
// few intervals in the past
let fake_now = first_interval.start()
- first_interval.length
- first_interval.length
- first_interval.length;
assert_eq!(
first_interval
.previous_interval()
.unwrap()
.previous_interval()
.unwrap()
.previous_interval()
.unwrap(),
first_interval.current(fake_now).unwrap()
);
// few intervals in the future
let fake_now = first_interval.end()
+ first_interval.length
+ first_interval.length
+ first_interval.length;
assert_eq!(
first_interval
.next_interval()
.next_interval()
.next_interval(),
first_interval.current(fake_now).unwrap()
);
}
}
@@ -5,7 +5,6 @@ mod delegation;
pub mod error;
pub mod events;
mod gateway;
mod interval;
pub mod mixnode;
mod msg;
mod types;
@@ -18,9 +17,6 @@ pub use delegation::{
PagedMixDelegationsResponse,
};
pub use gateway::{Gateway, GatewayBond, GatewayOwnershipResponse, PagedGatewayResponse};
pub use interval::Interval;
pub use mixnode::{
Layer, MixNode, MixNodeBond, MixOwnershipResponse, PagedMixnodeResponse, RewardedSetNodeStatus,
};
pub use mixnode::{Layer, MixNode, MixNodeBond, MixOwnershipResponse, PagedMixnodeResponse};
pub use msg::*;
pub use types::*;
@@ -5,7 +5,7 @@ use crate::{IdentityKey, SphinxKey};
use az::CheckedCast;
use cosmwasm_std::{coin, Addr, Coin, Uint128};
use log::error;
use network_defaults::DEFAULT_OPERATOR_INTERVAL_COST;
use network_defaults::DEFAULT_OPERATOR_EPOCH_COST;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
@@ -18,19 +18,6 @@ fixed::const_fixed_from_int! {
const ONE: U128 = 1;
}
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd, Serialize, JsonSchema)]
pub enum RewardedSetNodeStatus {
Active,
Standby,
}
impl RewardedSetNodeStatus {
pub fn is_active(&self) -> bool {
matches!(self, RewardedSetNodeStatus::Active)
}
}
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize, JsonSchema)]
pub struct MixNode {
@@ -146,7 +133,7 @@ impl NodeRewardParams {
}
pub fn operator_cost(&self) -> U128 {
U128::from_num(self.uptime.u128() / 100u128 * DEFAULT_OPERATOR_INTERVAL_COST as u128)
U128::from_num(self.uptime.u128() / 100u128 * DEFAULT_OPERATOR_EPOCH_COST as u128)
}
pub fn set_reward_blockstamp(&mut self, blockstamp: u64) {
@@ -338,7 +325,7 @@ impl MixNodeBond {
&self.mix_node
}
pub fn total_bond(&self) -> Option<u128> {
pub fn total_stake(&self) -> Option<u128> {
if self.pledge_amount.denom != self.total_delegation.denom {
None
} else {
@@ -508,7 +495,7 @@ impl PartialOrd for MixNodeBond {
}
impl Display for MixNodeBond {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"amount: {} {}, owner: {}, identity: {}",
@@ -23,10 +23,6 @@ pub enum ExecuteMsg {
UpdateMixnodeConfig {
profit_margin_percent: u8,
},
UpdateMixnodeConfigOnBehalf {
profit_margin_percent: u8,
owner: String,
},
BondGateway {
gateway: Gateway,
owner_signature: String,
@@ -42,18 +38,28 @@ pub enum ExecuteMsg {
mix_identity: IdentityKey,
},
BeginMixnodeRewarding {
// nonce of the current rewarding interval
rewarding_interval_nonce: u32,
},
FinishMixnodeRewarding {
// nonce of the current rewarding interval
rewarding_interval_nonce: u32,
},
RewardMixnode {
identity: IdentityKey,
// percentage value in range 0-100
params: NodeRewardParams,
// id of the current rewarding interval
interval_id: u32,
// nonce of the current rewarding interval
rewarding_interval_nonce: u32,
},
RewardNextMixDelegators {
mix_identity: IdentityKey,
// id of the current rewarding interval
interval_id: u32,
// nonce of the current rewarding interval
rewarding_interval_nonce: u32,
},
DelegateToMixnodeOnBehalf {
mix_identity: IdentityKey,
@@ -79,11 +85,6 @@ pub enum ExecuteMsg {
UnbondGatewayOnBehalf {
owner: String,
},
WriteRewardedSet {
rewarded_set: Vec<IdentityKey>,
expected_active_set_size: u32,
},
AdvanceCurrentInterval {},
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
@@ -105,6 +106,7 @@ pub enum QueryMsg {
address: String,
},
StateParams {},
CurrentRewardingInterval {},
// gets all [paged] delegations in the entire network
// TODO: do we even want that?
GetAllNetworkDelegations {
@@ -135,25 +137,12 @@ pub enum QueryMsg {
LayerDistribution {},
GetRewardPool {},
GetCirculatingSupply {},
GetIntervalRewardPercent {},
GetEpochRewardPercent {},
GetSybilResistancePercent {},
GetActiveSetWorkFactor {},
GetRewardingStatus {
mix_identity: IdentityKey,
interval_id: u32,
rewarding_interval_nonce: u32,
},
GetRewardedSet {
height: Option<u64>,
start_after: Option<IdentityKey>,
limit: Option<u32>,
},
GetRewardedSetHeightsForInterval {
interval_id: u32,
},
GetRewardedSetUpdateDetails {},
GetCurrentRewardedSetHeight {},
GetCurrentInterval {},
GetRewardedSetRefreshBlocks {},
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::mixnode::DelegatorRewardParams;
use crate::{Layer, RewardedSetNodeStatus};
use crate::Layer;
use cosmwasm_std::{Addr, Uint128};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -27,12 +27,19 @@ impl LayerDistribution {
}
}
#[derive(Debug, Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq)]
pub struct RewardingIntervalResponse {
pub current_rewarding_interval_starting_block: u64,
pub current_rewarding_interval_nonce: u32,
pub rewarding_in_progress: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct ContractStateParams {
// so currently interval_length is being unused and validator API performs rewarding
// based on its own interval length config value. I guess that's fine for time being
// so currently epoch_length is being unused and validator API performs rewarding
// based on its own epoch length config value. I guess that's fine for time being
// however, in the future, the contract constant should be controlling it instead.
// pub interval_length: u32, // length of a rewarding interval/interval, expressed in hours
// pub epoch_length: u32, // length of a rewarding epoch/interval, expressed in hours
pub minimum_mixnode_pledge: Uint128, // minimum amount a mixnode must pledge to get into the system
pub minimum_gateway_pledge: Uint128, // minimum amount a gateway must pledge to get into the system
@@ -43,6 +50,7 @@ pub struct ContractStateParams {
// subset of rewarded mixnodes that are actively receiving mix traffic
// used to handle shorter-term (e.g. hourly) fluctuations of demand
pub mixnode_active_set_size: u32,
pub active_set_work_factor: u8,
}
impl Display for ContractStateParams {
@@ -67,6 +75,11 @@ impl Display for ContractStateParams {
f,
"mixnode active set size: {}",
self.mixnode_active_set_size
)?;
write!(
f,
"mixnode active set work factor: {}",
self.active_set_work_factor
)
}
}
@@ -123,23 +136,3 @@ pub struct MixnetContractVersion {
pub type IdentityKey = String;
pub type IdentityKeyRef<'a> = &'a str;
pub type SphinxKey = String;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct PagedRewardedSetResponse {
pub identities: Vec<(IdentityKey, RewardedSetNodeStatus)>,
pub start_next_after: Option<IdentityKey>,
pub at_height: u64,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct RewardedSetUpdateDetails {
pub refresh_rate_blocks: u64,
pub last_refreshed_block: u64,
pub current_height: u64,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct IntervalRewardedSetHeightsResponse {
pub interval_id: u32,
pub heights: Vec<u64>,
}
Binary file not shown.
@@ -7,9 +7,3 @@ edition = "2021"
[dependencies]
cosmwasm-std = "1.0.0-beta3"
mixnet-contract-common = { path = "../mixnet-contract" }
serde = { version = "1.0", features = ["derive"] }
schemars = "0.8"
cw-storage-plus = "0.11.1"
config = { path = "../../config" }
ts-rs = { version = "*", optional = true }
@@ -15,7 +15,6 @@ pub const VESTING_GATEWAY_BONDING_EVENT_TYPE: &str = "vesting_gateway_bonding";
pub const VESTING_GATEWAY_UNBONDING_EVENT_TYPE: &str = "vesting_gateway_unbonding";
pub const VESTING_MIXNODE_BONDING_EVENT_TYPE: &str = "vesting_mixnode_bonding";
pub const VESTING_MIXNODE_UNBONDING_EVENT_TYPE: &str = "vesting_mixnode_unbonding";
pub const VESTING_UPDATE_MIXNODE_CONFIG_EVENT_TYPE: &str = "vesting_update_mixnode_config";
pub const TRACK_MIXNODE_UNBOND_EVENT_TYPE: &str = "track_mixnode_unbond";
pub const TRACK_GATEWAY_UNBOND_EVENT_TYPE: &str = "track_gateway_unbond";
@@ -109,10 +108,6 @@ pub fn new_vesting_mixnode_bonding_event() -> Event {
Event::new(VESTING_MIXNODE_BONDING_EVENT_TYPE)
}
pub fn new_vesting_update_mixnode_config_event() -> Event {
Event::new(VESTING_UPDATE_MIXNODE_CONFIG_EVENT_TYPE)
}
pub fn new_vesting_mixnode_unbonding_event() -> Event {
Event::new(VESTING_MIXNODE_UNBONDING_EVENT_TYPE)
}
@@ -1,70 +1,4 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use config::defaults::DENOM;
use cosmwasm_std::{Coin, Timestamp};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub mod events;
pub mod messages;
pub fn one_ucoin() -> Coin {
Coin::new(1, DENOM)
}
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, JsonSchema)]
pub enum Period {
Before,
In(usize),
After,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct PledgeData {
amount: Coin,
block_time: Timestamp,
}
impl PledgeData {
pub fn amount(&self) -> Coin {
self.amount.clone()
}
pub fn block_time(&self) -> Timestamp {
self.block_time
}
pub fn new(amount: Coin, block_time: Timestamp) -> Self {
Self { amount, block_time }
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct OriginalVestingResponse {
amount: Coin,
number_of_periods: usize,
period_duration: u64,
}
impl OriginalVestingResponse {
pub fn amount(&self) -> Coin {
self.amount.clone()
}
pub fn number_of_periods(&self) -> usize {
self.number_of_periods
}
pub fn period_duration(&self) -> u64 {
self.period_duration
}
pub fn new(amount: Coin, number_of_periods: usize, period_duration: u64) -> Self {
Self {
amount,
number_of_periods,
period_duration,
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "credentials"
version = "0.1.0"
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1 -1
View File
@@ -27,7 +27,7 @@ pub struct BandwidthVoucherAttributes {
pub binding_number: PrivateAttribute,
// the value (e.g., bandwidth) encoded in this voucher
pub voucher_value: PublicAttribute,
// a field with public information, e.g., type of voucher, interval etc.
// a field with public information, e.g., type of voucher, epoch etc.
pub voucher_info: PublicAttribute,
}
+1 -1
View File
@@ -28,7 +28,7 @@ use crate::error::Error;
/// use credentials::obtain_aggregate_verification_key;
///
/// async fn example() -> Result<(), ParseError> {
/// let validators = vec!["https://sandbox-validator1.nymtech.net/api".parse()?, "https://sandbox-validator2.nymtech.net/api".parse()?];
/// let validators = vec!["https://testnet-milhon-validator1.nymtech.net/api".parse()?, "https://testnet-milhon-validator2.nymtech.net/api".parse()?];
/// let aggregated_key = obtain_aggregate_verification_key(&validators).await;
/// // deal with the obtained Result
/// Ok(())
+1 -1
View File
@@ -2,7 +2,7 @@
name = "crypto"
version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1 -1
View File
@@ -2,7 +2,7 @@
name = "mixnode-common"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+2 -1
View File
@@ -2,7 +2,7 @@
name = "network-defaults"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -11,3 +11,4 @@ cfg-if = "1.0.0"
hex-literal = "0.3.3"
serde = {version = "1.0", features = ["derive"]}
url = "2.2"
time = { version = "0.3", features = ["macros"] }

Some files were not shown because too many files have changed in this diff Show More