Skip to content

Commit

Permalink
Overhaul of blockchain API, massive sync speedup (#3)
Browse files Browse the repository at this point in the history
- Use new faster CN crypto
- Use new Karbo daemon's JSON RPC methods made especially for this wallet to speedup sync
  • Loading branch information
aivve authored Oct 16, 2020
1 parent b7e4cfe commit 9f2f61c
Show file tree
Hide file tree
Showing 43 changed files with 3,824 additions and 1,951 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
.idea/
*.iml
node_modules
src_api/cache*
src_api/lastRun.txt
src/**/*.js
src/**/*.js.map
!src/lib/*.js
Expand Down
7 changes: 2 additions & 5 deletions Deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ You also need to build some files that are dynamically generated like the manife
This task is doable with :
```
npm install
nodejs ./node_modules/typescript/bin/tsc --project tsconfig.prod.json
nodejs build.js
node ./node_modules/typescript/bin/tsc --project tsconfig.prod.json
node build.js
```
The first task install dependencies (typescript) and the text one compile the typescript code.
We are using a custom tsconfig file which is optimized for production.
Expand All @@ -21,9 +21,6 @@ That's all

# Deploy
All the content of the src directory needs to be exposed with a web-server.
You will also need to expose the content of the src_api content to an endpoint which can interpret PHP.
By default the configuration looks at domainname.com/api/


# Permissions
The API stores precomputed data for performances in a directory called cache/ in the same directory of the API code (PHP code).
Expand Down
30 changes: 0 additions & 30 deletions debug-router.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h1>Karbo Wallet API relay</h1>
<script src="lib/nacl-util.min.js"></script>
<script src="lib/base58.js"></script>
<!--<script src="lib/mnemonic.js"></script>-->
<script src="lib/cn_utils.js"></script>
<!--script src="lib/cn_utils.js"></script-->
<script data-main="api.js" src="lib/require.js"></script>

</body>
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ global.config = {

idleTimeout: 30,
idleWarningDuration: 20,
syncBlockCount: 50,

coinSymbol: 'KRB',
openAliasPrefix: "krb",
Expand Down
1 change: 1 addition & 0 deletions src/d/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ declare var config : {
txChargeAddress: string,
idleTimeout: number,
idleWarningDuration: number,
syncBlockCount: number,
maxBlockNumber: number,
avgBlockTime: number,
};
18 changes: 17 additions & 1 deletion src/d/nacl.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
declare var nacl : any;
declare var nacl : {
ll:{
ge_scalarmult:(a : Uint8Array, b : Uint8Array)=>Uint8Array,
ge_double_scalarmult_base_vartime:(a : Uint8Array, b : Uint8Array, c : Uint8Array)=>Uint8Array,
ge_double_scalarmult_postcomp_vartime:(a : Uint8Array, b : Uint8Array, c : Uint8Array, d : Uint8Array)=>Uint8Array,
ge_add:(a : Uint8Array, b : Uint8Array)=>Uint8Array,
ge_scalarmult_base:(a : Uint8Array)=>Uint8Array
},
secretbox:any,
//open:(encrypted:Uint8Array, nonce:Uint8Array, privKey:Uint8Array)=>Uint8Array;
util:{
encodeBase64:(value : Uint8Array)=>string,
},
randomBytes:(bits : number) => Uint8Array
};

declare function keccak_256(bin : Uint8Array) : string;
80 changes: 80 additions & 0 deletions src/filters/Filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Copyright (c) 2018-2020, ExploShot
* Copyright (c) 2018-2020, The Qwertycoin Project
* Copyright (c) 2020, The Masari Project
*
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* ==> Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* ==> Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* ==> Neither the name of Qwertycoin nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

export function VueFilterSatoshis(value: number) {
return '₿ ' + value.toFixed(8)
}

export function VueFilterPiconero(value: number) {
return value.toFixed(12)
}

export function VueFilterFiat(value: number, currency: string) {
if (currency == 'usd' || currency == 'aud' || currency == 'cad' || currency == 'nzd') {
return '$ ' + value.toFixed(2);
}
if (currency == 'eur') {
return '€ ' + value.toFixed(2);
}
if (currency == 'jpy') {
return '¥ ' + value.toFixed(2);
}
if (currency == 'gbp') {
return '£ ' + value.toFixed(2);
}
if (currency == 'chf') {
return 'Fr. ' + value.toFixed(2);
}
if (currency == 'sek') {
return 'kr ' + value.toFixed(2);
}
if (currency == 'czk') {
return 'CZK ' + value.toFixed(2);
}
if (currency == 'eth') {
return 'Ξ ' + value.toFixed(2);
}
if (currency == 'ltc') {
return 'Ł ' + value.toFixed(2);
}
}

export function VueFilterHashrate(hashrate: number) {
let i = 0;
let byteUnits = ['H', 'kH', 'MH', 'GH', 'TH', 'PH', 'EH', 'ZH', 'YH'];

while (hashrate > 1000) {
hashrate = hashrate / 1000;
i++;
}

return hashrate.toFixed(2) + byteUnits[i];
}
92 changes: 48 additions & 44 deletions src/model/AppState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,27 @@
*/

import {DependencyInjectorInstance} from "../lib/numbersLab/DependencyInjector";
import {BlockchainExplorerRpc2, WalletWatchdog} from "./blockchain/BlockchainExplorerRpc2";
import {Wallet} from "./Wallet";
import {BlockchainExplorerProvider} from "../providers/BlockchainExplorerProvider";
import {Observable} from "../lib/numbersLab/Observable";
import {WalletRepository} from "./WalletRepository";
import {BlockchainExplorer} from "./blockchain/BlockchainExplorer";
import {Constants} from "./Constants";
import {BlockchainExplorer, RawDaemon_Transaction} from "./blockchain/BlockchainExplorer";
import {TransactionsExplorer} from "./TransactionsExplorer";
import {WalletWatchdog} from "./WalletWatchdog";

export class WalletWorker{
wallet : Wallet;
password : string;
export class WalletWorker {
wallet: Wallet;
password: string;

intervalSave = 0;

constructor(wallet: Wallet, password:string) {
constructor(wallet: Wallet, password: string) {
this.wallet = wallet;
this.password = password;
let self = this;
wallet.addObserver(Observable.EVENT_MODIFIED, function(){
if(self.intervalSave === 0)
self.intervalSave = <any>setTimeout(function(){
wallet.addObserver(Observable.EVENT_MODIFIED, function () {
if (self.intervalSave === 0)
self.intervalSave = setTimeout(function () {
self.save();
self.intervalSave = 0;
}, 1000);
Expand All @@ -44,65 +43,68 @@ export class WalletWorker{
this.save();
}

save(){
save() {
WalletRepository.save(this.wallet, this.password);
}
}

export class AppState{
export class AppState {

static openWallet(wallet : Wallet, password:string){
static openWallet(wallet: Wallet, password: string) {
let walletWorker = new WalletWorker(wallet, password);

DependencyInjectorInstance().register(Wallet.name,wallet);
DependencyInjectorInstance().register(Wallet.name, wallet);
let watchdog = BlockchainExplorerProvider.getInstance().watchdog(wallet);
DependencyInjectorInstance().register(WalletWatchdog.name,watchdog);
DependencyInjectorInstance().register(WalletWorker.name,walletWorker);
DependencyInjectorInstance().register(WalletWatchdog.name, watchdog);
DependencyInjectorInstance().register(WalletWorker.name, walletWorker);

$('body').addClass('connected');
if(wallet.isViewOnly())
if (wallet.isViewOnly())
$('body').addClass('viewOnlyWallet');
}

static disconnect(){
let wallet : Wallet = DependencyInjectorInstance().getInstance(Wallet.name,'default', false);
let walletWorker : WalletWorker = DependencyInjectorInstance().getInstance(WalletWorker.name,'default', false);
let walletWatchdog : WalletWatchdog = DependencyInjectorInstance().getInstance(WalletWatchdog.name,'default', false);
if(walletWatchdog !== null)
static disconnect() {
let wallet: Wallet = DependencyInjectorInstance().getInstance(Wallet.name, 'default', false);
let walletWorker: WalletWorker = DependencyInjectorInstance().getInstance(WalletWorker.name, 'default', false);
let walletWatchdog: WalletWatchdog = DependencyInjectorInstance().getInstance(WalletWatchdog.name, 'default', false);
if (walletWatchdog !== null)
walletWatchdog.stop();

DependencyInjectorInstance().register(Wallet.name,undefined,'default');
DependencyInjectorInstance().register(WalletWorker.name,undefined,'default');
DependencyInjectorInstance().register(WalletWatchdog.name,undefined,'default');
DependencyInjectorInstance().register(Wallet.name, undefined, 'default');
DependencyInjectorInstance().register(WalletWorker.name, undefined, 'default');
DependencyInjectorInstance().register(WalletWatchdog.name, undefined, 'default');
$('body').removeClass('connected');
$('body').removeClass('viewOnlyWallet');
}

private static leftMenuEnabled = false;
static enableLeftMenu(){
if(!this.leftMenuEnabled) {

static enableLeftMenu() {
if (!this.leftMenuEnabled) {
this.leftMenuEnabled = true;
$('body').removeClass('menuDisabled');
}
}
static disableLeftMenu(){
if(this.leftMenuEnabled) {

static disableLeftMenu() {
if (this.leftMenuEnabled) {
this.leftMenuEnabled = false;
$('body').addClass('menuDisabled');
}
}

static askUserOpenWallet(redirectToHome:boolean=true){
static askUserOpenWallet(redirectToHome: boolean = true) {
let self = this;
return new Promise<void>(function (resolve, reject) {

swal({
title: i18n.t('global.openWalletModal.title'),
input: 'password',
showCancelButton: true,
confirmButtonText: i18n.t('global.openWalletModal.confirmText'),
cancelButtonText: i18n.t('global.openWalletModal.cancelText'),
}).then((result:any) => {
setTimeout(function(){//for async
}).then((result: any) => {
setTimeout(function () { //for async
if (result.value) {
swal({
type: 'info',
Expand All @@ -115,8 +117,8 @@ export class AppState{
let savePassword = result.value;
// let password = prompt();
let memoryWallet = DependencyInjectorInstance().getInstance(Wallet.name, 'default', false);
if(memoryWallet === null){
WalletRepository.getLocalWalletWithPassword(savePassword).then((wallet : Wallet|null) => {
if (memoryWallet === null) {
WalletRepository.getLocalWalletWithPassword(savePassword).then((wallet: Wallet | null) => {
//console.log(wallet);
if (wallet !== null) {
wallet.recalculateIfNotViewOnly();
Expand All @@ -130,19 +132,23 @@ export class AppState{
}
let blockchainHeightToRescan = Object.keys(blockchainHeightToRescanObj);
if (blockchainHeightToRescan.length > 0) {
let blockchainExplorer: BlockchainExplorerRpc2 = BlockchainExplorerProvider.getInstance();
let blockchainExplorer: BlockchainExplorer = BlockchainExplorerProvider.getInstance();

let promisesBlocks = [];
for (let height of blockchainHeightToRescan) {
promisesBlocks.push(blockchainExplorer.getTransactionsForBlocks(parseInt(height)));
promisesBlocks.push(blockchainExplorer.getTransactionsForBlocks(parseInt(height), parseInt(height), wallet.options.checkMinerTx));
//console.log(`promisesBlocks.length: ${promisesBlocks.length}`);
}
Promise.all(promisesBlocks).then(function (arrayOfTxs: Array<RawDaemonTransaction[]>) {

Promise.all(promisesBlocks).then(function (arrayOfTxs: Array<RawDaemon_Transaction[]>) {
for (let txs of arrayOfTxs) {
for (let rawTx of txs) {
if (wallet !== null) {
let tx = TransactionsExplorer.parse(rawTx, wallet);
if (tx !== null)
if (tx !== null) {
console.log(`Added new Tx ${tx.hash} to wallet`);
wallet.addNew(tx);
}
}
}
}
Expand All @@ -167,16 +173,14 @@ export class AppState{
reject();
}
});
}else {
} else {
swal.close();
window.location.href = '#account';
}
}else
} else
reject();
},1);
}, 1);
});
});
}


}
}
Loading

0 comments on commit 9f2f61c

Please sign in to comment.