Skip to content

Commit

Permalink
Merge branch 'master' into governance-vue
Browse files Browse the repository at this point in the history
  • Loading branch information
Duddino authored Nov 19, 2024
2 parents db9f0b9 + 1fff522 commit 78fc1ea
Show file tree
Hide file tree
Showing 17 changed files with 74 additions and 183 deletions.
2 changes: 1 addition & 1 deletion cypress.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineConfig } from 'cypress';
import { existsSync, readFileSync } from 'fs';
import { existsSync } from 'fs';
import cypressPlayback from '@oreillymedia/cypress-playback/addTasks.js';
export default defineConfig({
e2e: {
Expand Down
3 changes: 3 additions & 0 deletions cypress/e2e/wallet_balance.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ describe('Wallet balance tests', () => {
matching: { ignores: ['hostname', 'port'] },
}).as('sync');
cy.visit('/');
cy.waitForLoading().should('be.visible');
cy.setExplorer(0);
cy.goToTab('dashboard');
cy.importWallet('DLabsktzGMnsK5K9uRTMCF6NoYNY6ET4Bb');
});
it('calculates balance correctly', () => {
Expand Down
16 changes: 8 additions & 8 deletions cypress/snapshots/html/snapshot.html

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,24 @@ Cypress.Commands.add(
}
);

Cypress.Commands.add('waitForLoading', () => {
cy.get('[data-testid="generateWallet"]');
});

Cypress.Commands.add('createWallet', (password) => {
cy.visit('');
cy.get('[data-testid="generateWallet"]').click();
const seedPhrase = cy.get('.seed-phrase').invoke('text');
cy.get('[data-testid="seedphraseModal"]').click();
cy.encryptWallet(password);
return seedPhrase;
});
Cypress.Commands.add('createVanityWallet', (prefix, password) => {
cy.visit('');
cy.get('[data-testid="vanityWalletButton"]').click();
cy.get('[data-testid="prefixInput"]').should('be.visible').type(prefix);
cy.get('[data-testid="generateBtn"]').click();
cy.encryptWallet(password);
});
Cypress.Commands.add('importWallet', (key, password) => {
cy.visit('');
cy.get('[data-testid="accWalletButton"]').click();
cy.get('[data-testid="secretInp"]').should('be.visible').type(key);
if (password)
Expand Down Expand Up @@ -77,3 +78,7 @@ Cypress.Commands.add('deleteWallet', () => {
cy.get('[data-testid="deleteWalletButton"]').click();
cy.get('[data-i18n="popupConfirm"]').click();
});
Cypress.Commands.add('setExplorer', (explorerNameOrIndex) => {
cy.goToTab('settings');
cy.get('#explorer').select(explorerNameOrIndex);
});
2 changes: 1 addition & 1 deletion cypress/support/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Cypress.Commands.add(
const snapshotPath = `cypress/snapshots/html/${snapshotName}.html`;

cy.task('fileExists', snapshotPath).then((exists) => {
if (exists && !process.env.CYPRESS_PLAYBACK_MODE === 'record') {
if (exists && process.env.CYPRESS_PLAYBACK_MODE !== 'record') {
cy.readFile(snapshotPath).then((expectedHtml) => {
expect(htmlContent === expectedHtml).to.equal(true);
});
Expand Down
3 changes: 0 additions & 3 deletions scripts/chain_params.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ export const COIN = 10 ** 8;
/** The maximum gap (absence of transactions within a range of derived addresses) before an account search ends */
export const MAX_ACCOUNT_GAP = 20;

/** The batch size of Shield block synchronisation */
export const SHIELD_BATCH_SYNC_SIZE = 32;

/** Transaction Sapling Version */
export const SAPLING_TX_VERSION = 3;

Expand Down
71 changes: 19 additions & 52 deletions scripts/dashboard/Activity.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ let txCount = 0;
const updating = ref(false);
const isHistorySynced = ref(false);
const rewardAmount = ref(0);
let nRewardUpdateHeight = 0;
const ticker = computed(() => cChainParams.current.TICKER);
const network = useNetwork();
function getActivityUrl(tx) {
Expand Down Expand Up @@ -70,6 +69,15 @@ const txMap = computed(() => {
};
});
function updateReward() {
if (!props.rewards) return;
let res = 0;
for (const tx of wallet.getHistoricalTxs()) {
if (tx.type !== HistoricalTxType.STAKE) continue;
res += tx.amount;
}
rewardAmount.value = res;
}
async function update(txToAdd = 0) {
// Return if wallet is not synced yet
if (!wallet.isSynced) {
Expand All @@ -88,22 +96,6 @@ async function update(txToAdd = 0) {
const historicalTxs = wallet.getHistoricalTxs();
// For Rewards: aggregate the total amount
if (props.rewards) {
for (const tx of historicalTxs) {
// If this Tx Height is under our last scanned height, we stop
if (tx.blockHeight <= nRewardUpdateHeight) break;
// Only compute rewards
if (tx.type != HistoricalTxType.STAKE) continue;
// Aggregate the total rewards
rewardAmount.value += tx.amount;
}
// Keep track of the scan block height
if (historicalTxs.length) {
nRewardUpdateHeight = historicalTxs[0].blockHeight;
}
}
let i = 0;
let found = 0;
while (found < txCount + txToAdd) {
Expand Down Expand Up @@ -143,9 +135,6 @@ async function parseTXs(arrTXs) {
minute: '2-digit',
hour12: true,
};
// And also keep track of our last Tx's timestamp, to re-use a cache, which is much faster than the slow `.toLocaleDateString`
let prevDateString = '';
let prevTimestamp = 0;
const cDB = await Database.getInstance();
const cAccount = await cDB.getAccount();
Expand All @@ -154,33 +143,19 @@ async function parseTXs(arrTXs) {
// If this Tx is older than 24h, then hit the `Date` cache logic, otherwise, use a `Time` and skip it
let strDate =
Date.now() / 1000 - cTx.time > 86400
? ''
? dateTime.toLocaleDateString(undefined, dateOptions)
: dateTime.toLocaleTimeString(undefined, timeOptions);
if (!strDate) {
if (
prevDateString &&
prevTimestamp - cTx.time * 1000 < 12 * 60 * 60 * 1000
) {
// Use our date cache
strDate = prevDateString;
} else {
// Create a new date, this Tx is too old to use the cache
prevDateString = dateTime.toLocaleDateString(
undefined,
dateOptions
);
strDate = prevDateString;
}
if (cTx.blockHeight === -1) {
strDate = 'Pending';
}
// Update the time cache
prevTimestamp = cTx.time * 1000;
// Coinbase Transactions (rewards) require coinbaseMaturity confs
const fConfirmed =
let fConfirmed =
cTx.blockHeight > 0 &&
blockCount - cTx.blockHeight >=
(cTx.type === HistoricalTxType.STAKE
? cChainParams.current.coinbaseMaturity
: 6);
(cTx.type === HistoricalTxType.STAKE
? cChainParams.current.coinbaseMaturity
: 6);
// Choose the content type, for the Dashboard; use a generative description, otherwise, a TX-ID
// let txContent = props.rewards ? cTx.id : 'Block Reward';
Expand Down Expand Up @@ -267,25 +242,17 @@ const rewardsText = computed(() => {
function reset() {
txs.value = [];
txCount = 0;
nRewardUpdateHeight = 0;
rewardAmount.value = 0;
update(0);
}
function getTxCount() {
return txCount;
}
getEventEmitter().on(
'transparent-sync-status-update',
(i, totalPages, done) => done && update()
);
getEventEmitter().on(
'shield-sync-status-update',
(blocks, totalBlocks, done) => done && update()
);
onMounted(() => update());
defineExpose({ update, reset, getTxCount });
defineExpose({ update, reset, getTxCount, updateReward });
</script>
<template>
Expand Down
1 change: 1 addition & 0 deletions scripts/dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ async function importFromDatabase() {
const account = await database.getAccount();
await wallet.setMasterKey({ mk: null });
activity.value?.reset();
getEventEmitter().emit('reset-activity');
if (account?.isHardware) {
await importWallet({ type: 'hardware', secret: account.publicKey });
} else if (wallet.isEncrypted) {
Expand Down
3 changes: 1 addition & 2 deletions scripts/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { openDB } from 'idb';
import Masternode from './masternode.js';
import { Settings } from './settings.js';
import { cChainParams } from './chain_params.js';
import { confirmPopup, sanitizeHTML, isSameType, isEmpty } from './misc.js';
import { isSameType, isEmpty } from './misc.js';
import { createAlert } from './alerts/alert.js';
import { PromoWallet } from './promos.js';
import { ALERTS, translation } from './i18n.js';
import { Account } from './accounts.js';
import { COutpoint, CTxIn, CTxOut, Transaction } from './transaction.js';
import { debugError, debugLog, DebugTopics } from './debug.js';
Expand Down
1 change: 0 additions & 1 deletion scripts/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import Governance from './governance/Governance.vue';
import { createPinia } from 'pinia';
import { cOracle } from './prices.js';

import pIconCopy from '../assets/icons/icon-copy.svg';
import pIconCheck from '../assets/icons/icon-check.svg';
import SideNavbar from './SideNavbar.vue';
import { AsyncInterval } from './async_interval.js';
Expand Down
2 changes: 1 addition & 1 deletion scripts/network/__mocks__/network_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class TestNetwork {
return 1;
});

getTxPage = vi.fn((nStartHeight, addr, n) => {
getTxPage = vi.fn((nStartHeight, addr, _n) => {
if (addr === 'DTSTGkncpC86sbEUZ2rCBLEe2aXSeZPLnC') {
// 1) Legacy mainnet wallet
// tx_1 provides a spendable balance of 0.1 * 10^8 satoshi
Expand Down
14 changes: 7 additions & 7 deletions scripts/network/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ export class Network {
}

async submitProposal({
name,
url,
nPayments,
start,
address,
monthlyPayment,
txid,
_name,
_url,
_nPayments,
_start,
_address,
_monthlyPayment,
_txid,
}) {
throw new Error('submitProposal must be implemented');
}
Expand Down
8 changes: 4 additions & 4 deletions scripts/network/network_manager.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExplorerNetwork, Network, RPCNodeNetwork } from './network.js';
import { ExplorerNetwork, RPCNodeNetwork } from './network.js';
import { cChainParams } from '../chain_params.js';
import { fAutoSwitch } from '../settings.js';
import { debugLog, DebugTopics, debugWarn } from '../debug.js';
Expand All @@ -7,17 +7,17 @@ import { getEventEmitter } from '../event_bus.js';

class NetworkManager {
/**
* @type {Network} - Current selected Explorer
* @type {import('./network.js').Network} - Current selected Explorer
*/
#currentExplorer;

/**
* @type {Network} - Current selected RPC node
* @type {import('./network.js').Network} - Current selected RPC node
*/
#currentNode;

/**
* @type {Array<Network>} - List of all available Networks
* @type {Array<import('./network.js').Network>} - List of all available Networks
*/
#networks = [];

Expand Down
3 changes: 3 additions & 0 deletions scripts/stake/Stake.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ async function updateColdStakingAddress() {
getEventEmitter().on('toggle-network', updateColdStakingAddress);
getEventEmitter().on('new-tx', () => {
activity?.value?.update();
activity?.value?.updateReward();
});
getEventEmitter().on('reset-activity', () => activity?.value?.reset());
onMounted(updateColdStakingAddress);
watch(coldStakingAddress, async (coldStakingAddress) => {
Expand Down
50 changes: 0 additions & 50 deletions scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,56 +75,6 @@ export function arrayToCSV(data) {
.join('\r\n'); // rows starting on new lines
}

/**
* Start a batch of promises, processing them concurrently up to `batchSize`.
* This does *not* run them in parallel. Only 1 CPU core is used
* @template T
* @param {(number)=>Promise<T>} promiseFactory - Function that spawns promises based
* on a number. 0 is the first, length-1 is the last one.
* @param {number} length - How many promises to spawn
* @param {number} batchSize - How many promises to spawn at a time
* @returns {Promise<T[]>} array of the return value of the promise.
* It's guaranteed to be sorted, i.e. it will contain
* [ await promsieFactory(0), await promisefactory(1), ... ]
* If the promises depend on each other, then behavior is undefined
*/
export async function startBatch(
promiseFactory,
length,
batchSize,
retryTime = 10000
) {
if (length === 0) {
return;
}
return new Promise((res) => {
const running = [];
let i = 0;
const startNext = async (current) => {
let result;
try {
result = await promiseFactory(current);
} catch (e) {
// Try again later
await sleep(retryTime);
return await startNext(current);
}
i++;
if (i < length) {
running.push(startNext(i));
} else {
(async () => res(await Promise.all(running)))();
}
return result;
};
// Start fisrt batchsize promises
for (i = 0; i < batchSize && i < length; i++) {
running.push(startNext(i));
}
--i;
});
}

/**
* An artificial sleep function to pause code execution
*
Expand Down
Loading

0 comments on commit 78fc1ea

Please sign in to comment.