From b5c39f3d4236c506776ded1b697362e44d35a497 Mon Sep 17 00:00:00 2001 From: Joohansson Date: Fri, 24 Jul 2020 10:29:12 +0200 Subject: [PATCH 001/823] added voxpopuli as new backend --- .../components/configure-app/configure-app.component.ts | 6 ++---- src/app/services/app-settings.service.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/app/components/configure-app/configure-app.component.ts b/src/app/components/configure-app/configure-app.component.ts index c4b0ae7b5..e85d3848b 100644 --- a/src/app/components/configure-app/configure-app.component.ts +++ b/src/app/components/configure-app/configure-app.component.ts @@ -149,7 +149,7 @@ export class ConfigureAppComponent implements OnInit { } async updateNodeStats(refresh=false) { - if ((this.serverAPIUpdated != this.appSettings.settings.serverAPI && this.selectedServer === 'random') || (refresh && !this.statsRefreshEnabled)) return + if ((!this.serverAPIUpdated || (this.serverAPIUpdated != this.appSettings.settings.serverAPI && this.selectedServer === 'random')) || (refresh && !this.statsRefreshEnabled)) return this.statsRefreshEnabled = false; try { let blockCount = await this.api.blockCount() @@ -368,7 +368,7 @@ export class ConfigureAppComponent implements OnInit { const custom = this.serverOptions.find(c => c.value === newServer); if (custom) { this.serverAPI = custom.api; - this.serverAPIUpdated = custom.api; + this.serverAPIUpdated = null; this.serverWS = custom.ws; this.serverAuth = custom.auth; } @@ -381,8 +381,6 @@ export class ConfigureAppComponent implements OnInit { this.nodeVendor = 'N/A'; this.nodeNetwork = 'N/A'; this.statsRefreshEnabled = newServer == 'random' ? false:true; - - this.updateNodeStats() } async clearWorkCache() { diff --git a/src/app/services/app-settings.service.ts b/src/app/services/app-settings.service.ts index a77699d83..a875d92c1 100644 --- a/src/app/services/app-settings.service.ts +++ b/src/app/services/app-settings.service.ts @@ -69,6 +69,14 @@ export class AppSettingsService { auth: null, shouldRandom: true, }, + { + name: 'VoxPopuli', + value: 'voxpopuli', + api: 'https://voxpopuli.network', + ws: 'wss://voxpopuli.network/websocket', + auth: null, + shouldRandom: true, + }, { name: 'Nanex.cc', value: 'nanex', From 0f32e36dc731a42265775031e4abc5f2037578d5 Mon Sep 17 00:00:00 2001 From: Tobias Palmer Date: Sat, 25 Jul 2020 22:11:43 +0200 Subject: [PATCH 002/823] docker hub --- .docker/nginx.conf | 14 ++++++++++++++ .dockerignore | 5 +++++ .github/workflows/docker-hub.yml | 19 +++++++++++++++++++ Dockerfile | 15 +++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 .docker/nginx.conf create mode 100644 .dockerignore create mode 100644 .github/workflows/docker-hub.yml create mode 100644 Dockerfile diff --git a/.docker/nginx.conf b/.docker/nginx.conf new file mode 100644 index 000000000..dae426265 --- /dev/null +++ b/.docker/nginx.conf @@ -0,0 +1,14 @@ +events{} + +http { + include /etc/nginx/mime.types; + server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + location / { + try_files $uri $uri/ /index.html; + } + } +} \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..3a94d7815 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +node_modules +npm-debug.log +dist +desktop-app/dist +desktop-app/build \ No newline at end of file diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml new file mode 100644 index 000000000..62dac6999 --- /dev/null +++ b/.github/workflows/docker-hub.yml @@ -0,0 +1,19 @@ +name: Release Drafter + +on: + push: + +jobs: + update_release_draft: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Build and push Docker images + uses: docker/build-push-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + repository: nault/nault + tag_with_ref: true diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..f96b77ee2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +# build the angular app +FROM node:12 AS build +WORKDIR /usr/src/app +RUN apt-get update && apt-get install -y \ + libudev-dev \ + libusb-1.0-0-dev +COPY package*.json ./ +RUN npm install +COPY . . +RUN npm run wallet:build + +# build the nginx hosting container +FROM nginx:1.19-alpine +COPY .docker/nginx.conf /etc/nginx/nginx.conf +COPY --from=build /usr/src/app/dist /usr/share/nginx/html \ No newline at end of file From 4085256062cd9240f0ec9ce96b1ce67f9a5d2df1 Mon Sep 17 00:00:00 2001 From: Tobias Palmer Date: Sat, 25 Jul 2020 22:15:14 +0200 Subject: [PATCH 003/823] fix docker hub name --- .github/workflows/docker-hub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index 62dac6999..aac3e7261 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -1,4 +1,4 @@ -name: Release Drafter +name: Docker Hub on: push: From 07cd3415aa4f696d34be0b635ca92eaaa8e12f5d Mon Sep 17 00:00:00 2001 From: Tobias Palmer Date: Sat, 25 Jul 2020 22:15:45 +0200 Subject: [PATCH 004/823] fix job name --- .github/workflows/docker-hub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index aac3e7261..d2dfa3bf8 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -4,7 +4,7 @@ on: push: jobs: - update_release_draft: + build_and_push: runs-on: ubuntu-latest steps: - name: Checkout code From b7c96d7a35496d7a9df98ffe6529b0c4edc4088f Mon Sep 17 00:00:00 2001 From: Tobias Palmer Date: Sun, 26 Jul 2020 12:07:27 +0200 Subject: [PATCH 005/823] push branches/tags/PRs --- .github/workflows/docker-hub.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index d2dfa3bf8..28258acd5 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -2,6 +2,11 @@ name: Docker Hub on: push: + branches: + - '*' + tags: + - '*' + pull_request: jobs: build_and_push: From bcecab3f67588d627d29960574a31bae0d43c087 Mon Sep 17 00:00:00 2001 From: Tobias Palmer Date: Sun, 26 Jul 2020 12:15:28 +0200 Subject: [PATCH 006/823] add comment --- .github/workflows/docker-hub.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index 28258acd5..5866bdd32 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -1,5 +1,6 @@ name: Docker Hub +# on all branches, tags, PRs on: push: branches: From 53364a754794ca03a022dd5dba2968b70f568564 Mon Sep 17 00:00:00 2001 From: Tobias Palmer Date: Sun, 26 Jul 2020 13:32:09 +0200 Subject: [PATCH 007/823] no pr for now --- .github/workflows/docker-hub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index 5866bdd32..722cd402c 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -7,7 +7,7 @@ on: - '*' tags: - '*' - pull_request: + #pull_request: jobs: build_and_push: From ba21c3edf64a40ca86123f9137bbf2f737e04d8b Mon Sep 17 00:00:00 2001 From: Joohansson Date: Sun, 26 Jul 2020 14:43:53 +0200 Subject: [PATCH 008/823] custom pow threshold option when remote signing --- src/app/components/sign/sign.component.html | 10 ++++-- src/app/components/sign/sign.component.ts | 26 ++++++++++++-- src/app/services/nano-block.service.ts | 4 +-- src/app/services/pow.service.ts | 38 ++++++++++++--------- src/app/services/util.service.ts | 11 ++++++ src/app/services/work-pool.service.ts | 8 ++--- 6 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/app/components/sign/sign.component.html b/src/app/components/sign/sign.component.html index 387ff3b5a..336ee2fa3 100644 --- a/src/app/components/sign/sign.component.html +++ b/src/app/components/sign/sign.component.html @@ -91,8 +91,14 @@

Process Nano Block



- Proof of Work
-

+ Proof of Work
+
+ +
+ +

diff --git a/src/app/components/sign/sign.component.ts b/src/app/components/sign/sign.component.ts index ef4ea873e..657200071 100644 --- a/src/app/components/sign/sign.component.ts +++ b/src/app/components/sign/sign.component.ts @@ -64,6 +64,18 @@ export class SignComponent implements OnInit { privateKey = null; // the final private key to sign with if using manual entry privateKeyExpanded = false; // if a private key is provided manually and it's expanded 128 char processedHash:string = null; + //TODO: These are based on the node v20 levels. With v21 the 8x will be the new 1x and max will be 8x due to the webgl threshold + thresholds = [ + { name: '1x', value: 1 }, + { name: '2x', value: 2 }, + { name: '4x', value: 4 }, + { name: '8x', value: 8 }, + { name: '16x', value: 16 }, + { name: '32x', value: 32 }, + { name: '64x', value: 64 }, + ]; + selectedThreshold = this.thresholds[0].value; + selectedThresholdOld = this.selectedThreshold; constructor( private router: ActivatedRoute, @@ -247,12 +259,22 @@ export class SignComponent implements OnInit { if (this.shouldGenWork) this.prepareWork(); } + changeThreshold() { + // multiplier has changed, clear the cache and recalculate + if (this.selectedThreshold !== this.selectedThresholdOld) { + let workBlock = this.txType === TxType.open ? this.util.account.getAccountPublicKey(this.toAccountID) : this.currentBlock.previous; + this.workPool.removeFromCache(workBlock); + console.log("PoW multiplier changed: Clearing cache") + this.powChange(); + } + } + prepareWork() { // The block has been verified if (this.toAccountID) { console.log('Precomputing work...') let workBlock = this.txType === TxType.open ? this.util.account.getAccountPublicKey(this.toAccountID) : this.currentBlock.previous; - this.workPool.addWorkToCache(workBlock); + this.workPool.addWorkToCache(workBlock, this.selectedThreshold); } } @@ -302,7 +324,7 @@ export class SignComponent implements OnInit { this.confirmingTransaction = true; // sign the block - const block = await this.nanoBlock.signOfflineBlock(walletAccount, this.currentBlock, this.previousBlock, this.txType, this.shouldGenWork, isLedger); + const block = await this.nanoBlock.signOfflineBlock(walletAccount, this.currentBlock, this.previousBlock, this.txType, this.shouldGenWork, this.selectedThreshold, isLedger); console.log('Signature: ' + block.signature || 'Error') console.log('Work: ' + block.work || 'Not applied') diff --git a/src/app/services/nano-block.service.ts b/src/app/services/nano-block.service.ts index 1aff6a12e..ceb4dae05 100644 --- a/src/app/services/nano-block.service.ts +++ b/src/app/services/nano-block.service.ts @@ -307,7 +307,7 @@ export class NanoBlockService { } // for signing block when offline - async signOfflineBlock(walletAccount:WalletAccount, block:StateBlock, prevBlock:StateBlock, type:TxType, genWork:boolean, ledger = false) { + async signOfflineBlock(walletAccount:WalletAccount, block:StateBlock, prevBlock:StateBlock, type:TxType, genWork:boolean, multiplier:number, ledger = false) { // special treatment if open block const openEquiv = type === TxType.open; console.log("Signing block of subtype: " + TxType[type]); @@ -370,7 +370,7 @@ export class NanoBlockService { this.notifications.sendInfo(`Generating Proof of Work...`); } - block.work = await this.workPool.getWork(workBlock); + block.work = await this.workPool.getWork(workBlock, multiplier); this.workPool.removeFromCache(workBlock); } return block; //return signed block (with or without work) diff --git a/src/app/services/pow.service.ts b/src/app/services/pow.service.ts index 7bcdd4284..d058a36f9 100644 --- a/src/app/services/pow.service.ts +++ b/src/app/services/pow.service.ts @@ -4,13 +4,12 @@ import {ApiService} from "./api.service"; import {NotificationService} from "./notification.service"; import { PoWSource } from './app-settings.service' import Worker from 'worker-loader!./../../assets/lib/cpupow.js'; +import {UtilService} from "./util.service"; const mod = window['Module']; //NEW v21 THRESHOLD BELOW TO BE ACTIVATED -//const webglThreshold = '0xFFFFFFF8' -const webglThreshold = '0xFFFFFFC0' -//const cpuThreshold = 'fffffff800000000' -const cpuThreshold = 'ffffffc000000000' +//const baseThreshold = 'fffffff800000000' +const baseThreshold = 'ffffffc000000000' const hardwareConcurrency = window.navigator.hardwareConcurrency || 2 const workerCount = Math.max(hardwareConcurrency - 1, 1) let workerList = [] @@ -25,7 +24,7 @@ export class PowService { parallelQueue = false; processingQueueItem = false; - constructor(private appSettings: AppSettingsService, private api: ApiService, private notifications: NotificationService) { } + constructor(private appSettings: AppSettingsService, private api: ApiService, private notifications: NotificationService, private util: UtilService) { } /** * Determine the best PoW Method available for this browser @@ -41,20 +40,20 @@ export class PowService { * Get PoW for a hash. If it's already being processed, return the promise. * Otherwise, add it into the queue and return when it is ready */ - async getPow(hash) { + async getPow(hash, multiplier) { const existingPoW = this.PoWPool.find(p => p.hash == hash); if (existingPoW) { return existingPoW.promise.promise; // Its okay if its resolved already } - return this.addQueueItem(hash); + return this.addQueueItem(hash, multiplier); } /** * Add a new hash into the queue to perform work on. * Returns a promise that is resolved when work is completed */ - addQueueItem(hash) { + addQueueItem(hash, multiplier) { const existingPoW = this.PoWPool.find(p => p.hash == hash); if (existingPoW) { return existingPoW.promise.promise; @@ -64,6 +63,7 @@ export class PowService { hash, work: null, promise: this.getDeferredPromise(), + multiplier: multiplier, }; this.PoWPool.push(queueItem); @@ -131,13 +131,13 @@ export class PowService { switch (powSource) { default: case 'server': - work = (await this.api.workGenerate(queueItem.hash).then(work => {return work.work}).catch(async err => {return await this.getHashCPUWorker(queueItem.hash)})); + work = (await this.api.workGenerate(queueItem.hash).then(work => {return work.work}).catch(async err => {return await this.getHashCPUWorker(queueItem.hash, queueItem.multiplier)})); break; case 'clientCPU': - work = await this.getHashCPUWorker(queueItem.hash); + work = await this.getHashCPUWorker(queueItem.hash, queueItem.multiplier); break; case 'clientWebGL': - work = await this.getHashWebGL(queueItem.hash); + work = await this.getHashWebGL(queueItem.hash, queueItem.multiplier); break; } @@ -180,7 +180,7 @@ export class PowService { /** * Generate PoW using CPU and WebWorkers */ - async getHashCPUWorker(hash) { + async getHashCPUWorker(hash, multiplier) { // console.log('Generating work using CPU for', hash); const response = this.getDeferredPromise(); @@ -197,8 +197,11 @@ export class PowService { }); */ + // calculate threshold from multiplier + const newThreshold = this.util.nano.difficultyFromMultiplier(multiplier, baseThreshold); + const work = () => new Promise(resolve => { - console.log('Generating work using CPU workers for', hash); + console.log('Generating work at threshold '+ newThreshold + ' using CPU workers for', hash); workerList = [] for (let i = 0; i < workerCount; i++) { //const worker = new Worker() @@ -207,7 +210,7 @@ export class PowService { blockHash: hash, workerIndex: i, workerCount: workerCount, - workThreshold: cpuThreshold, + workThreshold: newThreshold, }); worker.onmessage = (work) => { console.log(`CPU Worker: Found work (${work.data}) for ${hash} after ${(Date.now() - start) / 1000} seconds [${workerCount} Workers]`); @@ -228,8 +231,9 @@ export class PowService { /** * Generate PoW using WebGL */ - getHashWebGL(hash) { - console.log('Generating work using WebGL for', hash); + getHashWebGL(hash, multiplier) { + const newThreshold = this.util.nano.difficultyFromMultiplier(multiplier, baseThreshold); + console.log('Generating work at threshold '+ newThreshold + ' using WebGL for', hash); const response = this.getDeferredPromise(); @@ -240,7 +244,7 @@ export class PowService { response.resolve(work); }, n => {}, - webglThreshold + '0x'+newThreshold.substring(0,8).toUpperCase() // max threshold for webglpow is currently ffffffff00000000 ); } catch(error) { if (error.message === 'webgl2_required') { diff --git a/src/app/services/util.service.ts b/src/app/services/util.service.ts index bc358d3a6..564dbf5cc 100644 --- a/src/app/services/util.service.ts +++ b/src/app/services/util.service.ts @@ -75,6 +75,7 @@ export class UtilService { isValidIndex: isValidIndex, isValidSignature: isValidSignature, isValidWork: isValidWork, + difficultyFromMultiplier: difficultyFromMultiplier, }; array = { shuffle: shuffle @@ -381,6 +382,15 @@ function hashStateBlock(block:StateBlock) { blake.blake2bUpdate(context, hexToUint8(block.link)); return blake.blake2bFinal(context); } + +// Determine new difficulty from base difficulty (hexadecimal string) and a multiplier (float). Returns hex string +export function difficultyFromMultiplier(multiplier, base_difficulty) { + let big64 = new BigNumber(2).pow(64); + let big_multiplier = new BigNumber(multiplier); + let big_base = new BigNumber(base_difficulty,16); + return big64.minus((big64.minus(big_base).dividedToIntegerBy(big_multiplier))).toString(16); +} + // shuffle any array function shuffle(array) { var currentIndex = array.length, temporaryValue, randomIndex; @@ -473,5 +483,6 @@ const util = { isValidIndex: isValidIndex, isValidSignature: isValidSignature, isValidWork: isValidWork, + difficultyFromMultiplier: difficultyFromMultiplier, } }; diff --git a/src/app/services/work-pool.service.ts b/src/app/services/work-pool.service.ts index 4e875776e..fb2e389b6 100644 --- a/src/app/services/work-pool.service.ts +++ b/src/app/services/work-pool.service.ts @@ -16,8 +16,8 @@ export class WorkPoolService { } // A simple helper, which doesn't wait for a response (Used for pre-loading work) - public addWorkToCache(hash) { - this.getWork(hash); + public addWorkToCache(hash, multiplier=1) { + this.getWork(hash, multiplier); } // Remove a hash from from the cache @@ -42,14 +42,14 @@ export class WorkPoolService { } // Get work for a hash. Uses the cache, or the current setting for generating it. - public async getWork(hash) { + public async getWork(hash, multiplier=1) { const cached = this.workCache.find(p => p.hash == hash); if (cached && cached.work) { console.log('Using cached work: ' + cached.work) return cached.work; } - const work = await this.pow.getPow(hash); + const work = await this.pow.getPow(hash, multiplier); if (!work) { this.notifications.sendWarning(`Failed to retrieve work for ${hash}. Try a different PoW method.`); return null; From 2f59ff5717bca53f0152982423ef4702d9b392aa Mon Sep 17 00:00:00 2001 From: Joohansson Date: Sun, 26 Jul 2020 15:18:32 +0200 Subject: [PATCH 009/823] reset remote signing modal if view reloads while active --- .../account-details.component.ts | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/app/components/account-details/account-details.component.ts b/src/app/components/account-details/account-details.component.ts index b1584c555..3c4df59d5 100644 --- a/src/app/components/account-details/account-details.component.ts +++ b/src/app/components/account-details/account-details.component.ts @@ -1,5 +1,5 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; -import {ActivatedRoute, ChildActivationEnd, Router} from "@angular/router"; +import {ActivatedRoute, ChildActivationEnd, Router, NavigationEnd} from "@angular/router"; import {AddressBookService} from "../../services/address-book.service"; import {ApiService} from "../../services/api.service"; import {NotificationService} from "../../services/notification.service"; @@ -97,7 +97,14 @@ export class AccountDetailsComponent implements OnInit, OnDestroy { private util: UtilService, public settings: AppSettingsService, private nanoBlock: NanoBlockService, - private ninja: NinjaService) { } + private ninja: NinjaService) { + // to detect when the account changes if the view is already active + route.events.subscribe((val) => { + if (val instanceof NavigationEnd) { + this.clearRemoteVars(); // reset the modal content for remote signing + } + }); + } async ngOnInit() { const params = this.router.snapshot.queryParams; @@ -136,6 +143,28 @@ export class AccountDetailsComponent implements OnInit, OnDestroy { this.representativeList.push(...localReps); } + clearRemoteVars() { + this.selectedAmount = this.amounts[0]; + this.amount = null; + this.amountRaw = new BigNumber(0); + this.amountFiat = null; + this.rawAmount = new BigNumber(0); + this.fromAccount = {}; + this.toAccount = false; + this.toAccountID = ''; + this.toAddressBook = ''; + this.toAccountStatus = null; + this.repStatus = null; + this.qrString = null; + this.qrCodeImageBlock = null; + this.qrCodeImageBlockReceive = null; + this.blockHash = null; + this.blockHashReceive = null; + this.remoteVisible = false; + this.blockTypeSelected = this.blockTypes[0]; + this.representativeList = []; + } + async loadAccountDetails(refresh=false) { if (refresh && !this.statsRefreshEnabled) return this.statsRefreshEnabled = false; From 43327a9f8ebd3d3264d999389c26846909378818 Mon Sep 17 00:00:00 2001 From: keeri Date: Sun, 26 Jul 2020 19:40:38 +0000 Subject: [PATCH 010/823] better state handling for incoming tx status, and a label "Set to Receive Manually" --- src/app/app.component.html | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index 481e336d3..b97974be2 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -94,14 +94,26 @@
- - + + + + + + + + + + +