Skip to content

Commit

Permalink
refactor: purely rely on in-memory wallets based on transactions (#2209)
Browse files Browse the repository at this point in the history
* refactor: purely rely on in-memory wallets based on transactions

* refactor: purely rely on in-memory wallets based on transactions

* fix(core-database-postgres): compare vote balance objects

* test: use wallet manager instead of database

* refactor(core-database): use no longer used properties

* test(core-blockchain): expect call without arguments

* fix: await integrity verifier results

* test(core-blockchain): do not pass any arguments to buildWallets

* test(core-database): remove shutdown assertion

* test(core-api): wallet manager reference

* refactor(core-database-postgres): remove extraneous object.values call

* style(core-database-postgres): naming

* Update integrity-verifier.ts

* refactor(core-database-postgres): make __ methods private

* Update integrity-verifier.ts

* refactor(core-database-postgres): remove missed blocks from integrity verifier
  • Loading branch information
faustbrian authored and spkjp committed Mar 8, 2019
1 parent d00d471 commit 477db4c
Show file tree
Hide file tree
Showing 35 changed files with 108 additions and 296 deletions.
14 changes: 8 additions & 6 deletions __tests__/integration/core-api/__support__/setup.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { app } from "@arkecosystem/core-container";
import { Database } from "@arkecosystem/core-interfaces";
import delay from "delay";
import { registerWithContainer, setUpContainer } from "../../../utils/helpers/container";
import { plugin } from "../../../../packages/core-api/src/plugin";
import { registerWithContainer, setUpContainer } from "../../../utils/helpers/container";

import { delegates } from "../../../utils/fixtures";
import { generateRound } from "./utils/generate-round";

import { queries } from "../../../../packages/core-database-postgres/src/queries";
import { models } from "@arkecosystem/crypto";
import { sortBy } from "@arkecosystem/utils";

const round = generateRound(delegates.map(delegate => delegate.publicKey), 1);

Expand All @@ -32,8 +33,7 @@ async function setUp() {

const databaseService = app.resolvePlugin<Database.IDatabaseService>("database");
await databaseService.connection.roundsRepository.truncate();
await databaseService.buildWallets(1);
await databaseService.saveWallets(true);
await databaseService.buildWallets();
await databaseService.saveRound(round);

await registerWithContainer(plugin, options);
Expand All @@ -49,9 +49,11 @@ async function tearDown() {
async function calculateRanks() {
const databaseService = app.resolvePlugin<Database.IDatabaseService>("database");

const rows = await (databaseService.connection as any).query.manyOrNone(queries.spv.delegatesRanks);
const delegateWallets = Object.values(databaseService.walletManager.allByUsername()).sort(
(a: models.Wallet, b: models.Wallet) => b.voteBalance.comparedTo(a.voteBalance),
);

rows.forEach((delegate, i) => {
sortBy(delegateWallets, "publicKey").forEach((delegate, i) => {
const wallet = databaseService.walletManager.findByPublicKey(delegate.publicKey);
wallet.missedBlocks = +delegate.missedBlocks;
(wallet as any).rate = i + 1;
Expand Down
2 changes: 1 addition & 1 deletion __tests__/integration/core-blockchain/blockchain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ async function __resetToHeight1() {
// Make sure the wallet manager has been fed or else revertRound
// cannot determine the previous delegates. This is only necessary, because
// the database is not dropped after the unit tests are done.
await blockchain.database.buildWallets(lastBlock.data.height);
await blockchain.database.buildWallets();

// Index the genesis wallet or else revert block at height 1 fails
const generator = crypto.getAddress(genesisBlock.data.generatorPublicKey);
Expand Down
12 changes: 7 additions & 5 deletions __tests__/unit/core-api/__support__/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { registerWithContainer, setUpContainer } from "../../../utils/helpers/co
import { delegates } from "../../../utils/fixtures";
import { generateRound } from "./utils/generate-round";

import { queries } from "../../../../packages/core-database-postgres/src/queries";
import { models } from "@arkecosystem/crypto";
import { sortBy } from "@arkecosystem/utils";

const round = generateRound(delegates.map(delegate => delegate.publicKey), 1);

Expand All @@ -33,8 +34,7 @@ async function setUp() {

const databaseService = app.resolvePlugin<Database.IDatabaseService>("database");
await databaseService.connection.roundsRepository.truncate();
await databaseService.buildWallets(1);
await databaseService.saveWallets(true);
await databaseService.buildWallets();
await databaseService.saveRound(round);

await registerWithContainer(plugin, options);
Expand All @@ -50,9 +50,11 @@ async function tearDown() {
async function calculateRanks() {
const databaseService = app.resolvePlugin<Database.IDatabaseService>("database");

const rows = await (databaseService.connection as any).query.manyOrNone(queries.spv.delegatesRanks);
const delegateWallets = Object.values(databaseService.walletManager.allByUsername()).sort(
(a: models.Wallet, b: models.Wallet) => b.voteBalance.comparedTo(a.voteBalance),
);

rows.forEach((delegate, i) => {
sortBy(delegateWallets, "publicKey").forEach((delegate, i) => {
const wallet = databaseService.walletManager.findByPublicKey(delegate.publicKey);
wallet.missedBlocks = +delegate.missedBlocks;
(wallet as any).rate = i + 1;
Expand Down
2 changes: 1 addition & 1 deletion __tests__/unit/core-blockchain/blockchain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ async function __resetToHeight1() {
// Make sure the wallet manager has been fed or else revertRound
// cannot determine the previous delegates. This is only necessary, because
// the database is not dropped after the unit tests are done.
await blockchain.database.buildWallets(lastBlock.data.height);
await blockchain.database.buildWallets();

// Index the genesis wallet or else revert block at height 1 fails
const generator = crypto.getAddress(genesisBlock.data.generatorPublicKey);
Expand Down
8 changes: 2 additions & 6 deletions __tests__/unit/core-blockchain/state-machine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ describe("State Machine", () => {
// @ts-ignore
buildWallets: jest.spyOn(blockchain.database, "buildWallets").mockReturnValue(true),
// @ts-ignore
saveWallets: jest.spyOn(blockchain.database, "saveWallets").mockReturnValue(true),
// @ts-ignore
applyRound: jest.spyOn(blockchain.database, "applyRound").mockReturnValue(true),
// @ts-ignore
getActiveDelegates: jest.spyOn(blockchain.database, "getActiveDelegates").mockReturnValue(true),
Expand Down Expand Up @@ -290,8 +288,7 @@ describe("State Machine", () => {
stateStorage.networkStart = true;

await expect(() => actionMap.init()).toDispatch(blockchain, "STARTED");
expect(databaseMocks.buildWallets).toHaveBeenCalledWith(1);
expect(databaseMocks.saveWallets).toHaveBeenCalledWith(true);
expect(databaseMocks.buildWallets).toHaveBeenCalled();
expect(databaseMocks.applyRound).toHaveBeenCalledWith(1);

stateStorage.networkStart = false; // reset to default value
Expand All @@ -303,7 +300,7 @@ describe("State Machine", () => {
const loggerVerbose = jest.spyOn(logger, "verbose");

await expect(() => actionMap.init()).toDispatch(blockchain, "STARTED");
expect(databaseMocks.buildWallets).toHaveBeenCalledWith(1);
expect(databaseMocks.buildWallets).toHaveBeenCalled();
expect(loggerVerbose).toHaveBeenCalledWith(
"TEST SUITE DETECTED! SYNCING WALLETS AND STARTING IMMEDIATELY.",
);
Expand Down Expand Up @@ -334,7 +331,6 @@ describe("State Machine", () => {
expect(loggerWarn).toHaveBeenCalledWith(
"Rebuilding wallets table because of some inconsistencies. Most likely due to an unfortunate shutdown.",
);
expect(databaseMocks.saveWallets).toHaveBeenCalledWith(true);
});

it("should clean round data if new round starts at block.height + 1 (and dispatch STARTED)", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class DatabaseConnectionStub implements Database.IDatabaseConnection {
public walletsRepository: Database.IWalletsRepository;
public options: any;

public buildWallets(height: number): Promise<boolean> {
public buildWallets(): Promise<boolean> {
return undefined;
}

Expand Down Expand Up @@ -43,8 +43,4 @@ export class DatabaseConnectionStub implements Database.IDatabaseConnection {
public saveBlock(block: models.Block): Promise<any> {
return undefined;
}

public saveWallets(wallets: any[], force?: boolean): Promise<void> {
return undefined;
}
}
1 change: 0 additions & 1 deletion __tests__/unit/core-database/database-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ describe("Database Service", () => {

expect(emitter.on).toHaveBeenCalledWith("state:started", expect.toBeFunction());
expect(emitter.on).toHaveBeenCalledWith("wallet.created.cold", expect.toBeFunction());
expect(emitter.once).toHaveBeenCalledWith("shutdown", expect.toBeFunction());
});

describe("applyBlock", () => {
Expand Down
10 changes: 4 additions & 6 deletions packages/core-blockchain/src/state-machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,7 @@ blockchainMachine.actionMap = (blockchain: Blockchain) => ({
stateStorage.lastDownloadedBlock = block;

if (stateStorage.networkStart) {
await blockchain.database.buildWallets(block.data.height);
await blockchain.database.saveWallets(true);
await blockchain.database.buildWallets();
await blockchain.database.applyRound(block.data.height);
await blockchain.transactionPool.buildWallets();

Expand All @@ -181,7 +180,7 @@ blockchainMachine.actionMap = (blockchain: Blockchain) => ({
logger.verbose("TEST SUITE DETECTED! SYNCING WALLETS AND STARTING IMMEDIATELY.");

stateStorage.setLastBlock(new Block(config.get("genesisBlock")));
await blockchain.database.buildWallets(block.data.height);
await blockchain.database.buildWallets();

return blockchain.dispatch("STARTED");
}
Expand All @@ -198,13 +197,12 @@ blockchainMachine.actionMap = (blockchain: Blockchain) => ({
/** *******************************
* database init *
******************************* */
// SPV rebuild
const verifiedWalletsIntegrity = await blockchain.database.buildWallets(block.data.height);
// Integrity Verification
const verifiedWalletsIntegrity = await blockchain.database.buildWallets();
if (!verifiedWalletsIntegrity && block.data.height > 1) {
logger.warn(
"Rebuilding wallets table because of some inconsistencies. Most likely due to an unfortunate shutdown.",
);
await blockchain.database.saveWallets(true);
}

// NOTE: if the node is shutdown between round, the round has already been applied
Expand Down
3 changes: 0 additions & 3 deletions packages/core-container/src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,6 @@ export class Container implements container.IContainer {

// Wait for event to be emitted and give time to finish
await delay(1000);

// Save dirty wallets
await database.saveWallets(false);
}
} catch (error) {
// tslint:disable-next-line:no-console
Expand Down
2 changes: 1 addition & 1 deletion packages/core-database-postgres/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from "./postgres-connection";
export * from "./migrations";
export * from "./spv";
export * from "./integrity-verifier";
export * from "./models";
export * from "./repositories";
export * from "./plugin";
Loading

0 comments on commit 477db4c

Please sign in to comment.