Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core-transaction-pool): add type, interfaces and sort out structural issues #2448

Merged
merged 8 commits into from
Apr 20, 2019
9 changes: 7 additions & 2 deletions __tests__/integration/core-p2p/mocks/core-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jest.mock("@arkecosystem/core-container", () => {
};
}

if (name === "transactionPool") {
if (name === "transaction-pool") {
return {
transactionExists: jest.fn().mockReturnValue(false),
isSenderBlocked: jest.fn().mockReturnValue(false),
Expand All @@ -91,6 +91,11 @@ jest.mock("@arkecosystem/core-container", () => {
walletManager: {
canApply: jest.fn().mockReturnValue(true),
},
makeProcessor: jest.fn().mockReturnValue({
validate: jest.fn().mockImplementation(() => {
throw new Error("The payload contains invalid transaction.");
}),
}),
options: {
maxTransactionBytes: 10e6,
},
Expand All @@ -104,7 +109,7 @@ jest.mock("@arkecosystem/core-container", () => {
return defaults;
}

if (name === "transactionPool") {
if (name === "transaction-pool") {
return {
maxTransactionsPerRequest: 30,
};
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,53 @@ import { Blockchain, Container, Database } from "@arkecosystem/core-interfaces";
import { TransactionHandlerRegistry } from "@arkecosystem/core-transactions";
import { Blocks, Identities, Utils } from "@arkecosystem/crypto";
import { generateMnemonic } from "bip39";
import { WalletManager } from "../../../packages/core-transaction-pool/src/wallet-manager";
import { TransactionFactory } from "../../helpers/transaction-factory";
import { delegates, genesisBlock, wallets } from "../../utils/fixtures/unitnet";
import { generateWallets } from "../../utils/generators/wallets";
import { setUpFull, tearDownFull } from "./__support__/setup";

const satoshi = 1e8;
let container: Container.IContainer;
let PoolWalletManager;
let poolWalletManager;
let poolWalletManager: WalletManager;
let blockchain: Blockchain.IBlockchain;

beforeAll(async () => {
container = await setUpFull();

PoolWalletManager = require("../../../packages/core-transaction-pool/src").PoolWalletManager;
poolWalletManager = new PoolWalletManager();
poolWalletManager = new WalletManager();
blockchain = container.resolvePlugin<Blockchain.IBlockchain>("blockchain");
});

afterAll(async () => {
await tearDownFull();
});

describe("canApply", () => {
describe("throwIfApplyingFails", () => {
it("should add an error for delegate registration when username is already taken", () => {
const delegateReg = TransactionFactory.delegateRegistration("genesis_11")
.withNetwork("unitnet")
.withPassphrase(wallets[11].passphrase)
.build()[0];
const errors = [];

expect(poolWalletManager.canApply(delegateReg, errors)).toBeFalse();
expect(errors).toEqual([
`Failed to apply transaction, because the username '${
delegateReg.data.asset.delegate.username
}' is already registered.`,
]);

expect(() => poolWalletManager.throwIfApplyingFails(delegateReg)).toThrow(
JSON.stringify([
`Failed to apply transaction, because the username '${
delegateReg.data.asset.delegate.username
}' is already registered.`,
]),
);
});

it("should add an error when voting for a delegate that doesn't exist", () => {
const vote = TransactionFactory.vote(wallets[12].keys.publicKey)
.withNetwork("unitnet")
.withPassphrase(wallets[11].passphrase)
.build()[0];
const errors = [];

expect(poolWalletManager.canApply(vote, errors)).toBeFalse();
expect(errors).toEqual([`Failed to apply transaction, because only delegates can be voted.`]);
expect(() => poolWalletManager.throwIfApplyingFails(vote)).toThrow(
JSON.stringify([`Failed to apply transaction, because only delegates can be voted.`]),
);
});
});

Expand Down Expand Up @@ -145,15 +144,16 @@ describe("applyPoolTransactionToSender", () => {
.resolvePlugin<Database.IDatabaseService>("database")
.walletManager.findByPublicKey(transfer.data.senderPublicKey);

const errors = [];
if (poolWalletManager.canApply(transfer, errors)) {
try {
poolWalletManager.throwIfApplyingFails(transfer);

const senderWallet = poolWalletManager.findByPublicKey(transfer.data.senderPublicKey);
transactionHandler.applyToSender(transfer, senderWallet);

expect(t.from).toBe(delegate);
} else {
} catch (error) {
expect(t.from).toBe(walletsGen[0]);
expect(errors).toEqual(["Insufficient balance in the wallet."]);
expect(error.message).toEqual(JSON.stringify(["Insufficient balance in the wallet."]));
}

(container.resolvePlugin<Database.IDatabaseService>("database").walletManager as any).forgetByPublicKey(
Expand Down
2 changes: 1 addition & 1 deletion __tests__/unit/core-blockchain/mocks/transactionPool.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const transactionPool = {
buildWallets: () => null,
purgeBlock: () => null,
purgeByBlock: () => null,
acceptChainedBlock: () => null,
purgeSendersWithInvalidTransactions: () => null,
};
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ describe("Transactions Business Repository", () => {

it("should return no rows if senderId is an invalid address", async () => {
databaseService.walletManager = {
exists: addressOrPublicKey => false,
has: addressOrPublicKey => false,
} as Database.IWalletManager;
databaseService.connection.transactionsRepository = {
search: async parameters => parameters,
Expand All @@ -375,7 +375,7 @@ describe("Transactions Business Repository", () => {

it("should lookup senders address from senderId", async () => {
databaseService.walletManager = {
exists: addressOrPublicKey => true,
has: addressOrPublicKey => true,
findByAddress: address => ({ publicKey: "pubKey" }),
} as Database.IWalletManager;

Expand Down Expand Up @@ -487,10 +487,10 @@ describe("Transactions Business Repository", () => {
}));

databaseService.walletManager = {
exists: addressOrPublicKey => false,
has: addressOrPublicKey => false,
} as Database.IWalletManager;

jest.spyOn(databaseService.walletManager, "exists").mockReturnValue(false);
jest.spyOn(databaseService.walletManager, "has").mockReturnValue(false);

await transactionsBusinessRepository.search({
addresses: ["addy1", "addy2"],
Expand All @@ -513,8 +513,8 @@ describe("Transactions Business Repository", () => {
]),
}),
);
expect(databaseService.walletManager.exists).toHaveBeenNthCalledWith(1, "addy1");
expect(databaseService.walletManager.exists).toHaveBeenNthCalledWith(2, "addy2");
expect(databaseService.walletManager.has).toHaveBeenNthCalledWith(1, "addy1");
expect(databaseService.walletManager.has).toHaveBeenNthCalledWith(2, "addy2");
});

it("should cache blocks if cache-miss ", async () => {
Expand Down
4 changes: 0 additions & 4 deletions __tests__/unit/core-p2p/mocks/core-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ jest.mock("@arkecosystem/core-container", () => {
return defaults;
}

if (name === "transactionPool") {
return null;
}

return {};
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ describe("Peers handler", () => {
});
});

describe("postTransactions", () => {
// @TODO: this is an integration test, not a unit test
describe.skip("postTransactions", () => {
it("should handle the incoming transactions", async () => {
const result = await postTransactions({
service: createPeerService().service,
Expand Down
40 changes: 31 additions & 9 deletions __tests__/unit/core-transaction-pool/__stubs__/connection.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
import { TransactionPool } from "@arkecosystem/core-interfaces";
import { Blocks, Enums, Interfaces } from "@arkecosystem/crypto";
import { Dato } from "@faustbrian/dato";
import { ITransactionsProcessed } from "../../../../packages/core-transaction-pool/src/interfaces";
import { Memory } from "../../../../packages/core-transaction-pool/src/memory";
import { Storage } from "../../../../packages/core-transaction-pool/src/storage";
import { WalletManager } from "../../../../packages/core-transaction-pool/src/wallet-manager";

export class Connection implements TransactionPool.IConnection {
public options: any;
public loggedAllowedSenders: string[];
public walletManager: any;
public memory: any;
public storage: any;

constructor({
options,
walletManager,
memory,
storage,
}: {
options: Record<string, any>;
walletManager: WalletManager;
memory: Memory;
storage: Storage;
}) {
this.options = options;
this.walletManager = walletManager;
this.memory = memory;
this.storage = storage;
}

public async make(): Promise<this> {
return this;
Expand All @@ -27,12 +50,7 @@ export class Connection implements TransactionPool.IConnection {
return 0;
}

public addTransactions(
transactions: Interfaces.ITransaction[],
): {
added: Interfaces.ITransaction[];
notAdded: TransactionPool.IAddTransactionErrorResponse[];
} {
public addTransactions(transactions: Interfaces.ITransaction[]): ITransactionsProcessed {
return { added: [], notAdded: [] };
}

Expand Down Expand Up @@ -64,7 +82,7 @@ export class Connection implements TransactionPool.IConnection {
return null;
}

public getTransactionsData(start: number, size: number, property: string, maxBytes?: number): string[] | Buffer[] {
public getTransactionsData<T>(start: number, size: number, property: string, maxBytes?: number): T[] {
return null;
}

Expand All @@ -84,7 +102,11 @@ export class Connection implements TransactionPool.IConnection {
return;
}

public transactionExists(transactionId: string): any {
public makeProcessor(): TransactionPool.IProcessor {
return null;
}

public has(transactionId: string): any {
return;
}

Expand Down Expand Up @@ -112,7 +134,7 @@ export class Connection implements TransactionPool.IConnection {
return;
}

public purgeBlock(block: Blocks.Block): void {
public purgeByBlock(block: Blocks.Block): void {
return;
}

Expand Down
Loading