Skip to content

Commit

Permalink
refactor(core-magistrate): make bridgechain genesis hash only unique …
Browse files Browse the repository at this point in the history
…per wallet (#3523)
  • Loading branch information
air1one authored Feb 25, 2020
1 parent fbb82f3 commit 29019ce
Show file tree
Hide file tree
Showing 17 changed files with 124 additions and 122 deletions.
14 changes: 0 additions & 14 deletions __tests__/integration/core-api/handlers/bridgechains.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,6 @@ describe("API 2.0 - Bridgechains", () => {
});
});

describe("GET /bridgechains/:id", () => {
it("should GET bridgechains by id (genesisHash)", async () => {
const response = await utils.request("GET", `bridgechains/${bridgechainAsset.genesisHash}`);
expect(response).toBeSuccessfulResponse();
expect(response.data.data).toBeObject();
expect(response.data.data.publicKey).toEqual(publicKey);
expect(response.data.data.name).toEqual(bridgechainAsset.name);
expect(response.data.data.seedNodes).toEqual(bridgechainAsset.seedNodes);
expect(response.data.data.genesisHash).toEqual(bridgechainAsset.genesisHash);
expect(response.data.data.bridgechainRepository).toEqual(bridgechainAsset.bridgechainRepository);
expect(response.data.data.ports).toEqual(bridgechainAsset.ports);
});
});

describe("POST /bridgechains/search", () => {
it("should POST a search for bridgechains by name", async () => {
const response = await utils.request("POST", "bridgechains/search", {
Expand Down
13 changes: 13 additions & 0 deletions __tests__/integration/core-api/handlers/businesses.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ describe("API 2.0 - Businesses", () => {
});
});

describe("GET /businesses/:businessId/bridgechains/:bridgechainId", () => {
it.each(Object.entries(validIdentifiers))("should GET a business bridgechains by %s : %s", async (_, value) => {
const response = await utils.request(
"GET",
`businesses/${value}/bridgechains/${bridgechainAsset.genesisHash}`,
);
expect(response).toBeSuccessfulResponse();
expect(response.data.data).toBeObject();

expect(response.data.data.bridgechainAsset.genesisHash).toEqual(bridgechainAsset.genesisHash);
});
});

describe("POST /businesses/search", () => {
it("should POST a search for businesses by name", async () => {
const response = await utils.request("POST", "businesses/search", {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { State } from "@arkecosystem/core-interfaces";
import { Builders as MagistrateBuilders } from "@arkecosystem/core-magistrate-crypto";
import { Wallets } from "@arkecosystem/core-state";
import { Handlers } from "@arkecosystem/core-transactions";
import { Managers, Utils } from "@arkecosystem/crypto";
import { Identities, Managers, Utils } from "@arkecosystem/crypto";
import {
BridgechainAlreadyRegisteredError,
PortKeyMustBeValidPackageNameError,
Expand All @@ -18,11 +18,7 @@ import {
IBridgechainWalletAttributes,
IBusinessWalletAttributes,
} from "../../../../packages/core-magistrate-transactions/src/interfaces";
import {
bridgechainIndexer,
businessIndexer,
MagistrateIndex,
} from "../../../../packages/core-magistrate-transactions/src/wallet-manager";
import { businessIndexer, MagistrateIndex } from "../../../../packages/core-magistrate-transactions/src/wallet-manager";
import { bridgechainRegistrationAsset1, bridgechainRegistrationAsset2, businessRegistrationAsset1 } from "../helper";

jest.mock("@arkecosystem/core-container", () => {
Expand All @@ -49,6 +45,8 @@ let businessRegistrationBuilder: MagistrateBuilders.BusinessRegistrationBuilder;
let bridgechainRegistrationBuilder: MagistrateBuilders.BridgechainRegistrationBuilder;

let senderWallet: Wallets.Wallet;
const otherPassphrase = "other wallet passphrase";
let otherWallet: Wallets.Wallet;
let walletManager: State.IWalletManager;

Managers.configManager.setHeight(2); // aip11 (v2 transactions) is true from height 2 on testnet
Expand All @@ -68,12 +66,16 @@ describe("should test marketplace transaction handlers", () => {

walletManager = new Wallets.WalletManager();
walletManager.registerIndex(MagistrateIndex.Businesses, businessIndexer);
walletManager.registerIndex(MagistrateIndex.Bridgechains, bridgechainIndexer);

senderWallet = new Wallets.Wallet("ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo");
senderWallet.balance = Utils.BigNumber.make("500000000000000");
senderWallet.publicKey = "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37";
walletManager.reindex(senderWallet);

otherWallet = new Wallets.Wallet(Identities.Address.fromPassphrase(otherPassphrase));
otherWallet.balance = Utils.BigNumber.make("500000000000000");
otherWallet.publicKey = Identities.PublicKey.fromPassphrase(otherPassphrase);
walletManager.reindex(otherWallet);
});

describe("Bridgechain registration handler", () => {
Expand All @@ -98,6 +100,16 @@ describe("should test marketplace transaction handlers", () => {
.nonce("1")
.sign("clay harbor enemy utility margin pretty hub comic piece aerobic umbrella acquire");
await businessRegistrationHandler.applyToSender(businessRegistration.build(), walletManager);

const businessRegistration2 = businessRegistrationBuilder
.businessRegistrationAsset({
name: "business2",
website: "http://www.website2.com",
})
.nonce("1")
.sign(otherPassphrase);

await businessRegistrationHandler.applyToSender(businessRegistration2.build(), walletManager);
});

it("should pass because business is registered", async () => {
Expand All @@ -111,7 +123,7 @@ describe("should test marketplace transaction handlers", () => {
).toResolve();
});

it("should throw because bridgechain is already registered", async () => {
it("should throw because bridgechain is already registered by same wallet", async () => {
const actual = bridgechainRegistrationBuilder
.bridgechainRegistrationAsset(bridgechainRegistrationAsset1)
.nonce("2")
Expand All @@ -123,6 +135,23 @@ describe("should test marketplace transaction handlers", () => {
).rejects.toThrowError(BridgechainAlreadyRegisteredError);
});

it("should not throw when bridgechain is registered by another wallet", async () => {
const otherBridgechainRegistration = bridgechainRegistrationBuilder
.bridgechainRegistrationAsset(bridgechainRegistrationAsset1)
.nonce("2")
.sign(otherPassphrase);
await bridgechainRegistrationHandler.applyToSender(otherBridgechainRegistration.build(), walletManager);

const actual = bridgechainRegistrationBuilder
.bridgechainRegistrationAsset(bridgechainRegistrationAsset1)
.nonce("2")
.sign("clay harbor enemy utility margin pretty hub comic piece aerobic umbrella acquire");

await expect(
bridgechainRegistrationHandler.throwIfCannotBeApplied(actual.build(), senderWallet, walletManager),
).toResolve();
});

it.each([["@invalid/UPPERCASE"], ["@invalid/char)"]])(
"should throw because ports contains invalid package name",
async invalidName => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ import {
BusinessRegistrationTransactionHandler,
} from "../../../../packages/core-magistrate-transactions/src/handlers";
import { IBusinessWalletAttributes } from "../../../../packages/core-magistrate-transactions/src/interfaces";
import {
bridgechainIndexer,
businessIndexer,
MagistrateIndex,
} from "../../../../packages/core-magistrate-transactions/src/wallet-manager";
import { businessIndexer, MagistrateIndex } from "../../../../packages/core-magistrate-transactions/src/wallet-manager";
import { bridgechainRegistrationAsset1 } from "../helper";

jest.mock("@arkecosystem/core-container", () => {
Expand Down Expand Up @@ -71,7 +67,6 @@ describe("Bridgechain resignation handler", () => {

walletManager = new Wallets.WalletManager();
walletManager.registerIndex(MagistrateIndex.Businesses, businessIndexer);
walletManager.registerIndex(MagistrateIndex.Bridgechains, bridgechainIndexer);

senderWallet = new Wallets.Wallet("ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo");
senderWallet.balance = Utils.BigNumber.make("500000000000000");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ import {
BridgechainUpdateTransactionHandler,
BusinessRegistrationTransactionHandler,
} from "../../../../packages/core-magistrate-transactions/src/handlers";
import {
bridgechainIndexer,
businessIndexer,
MagistrateIndex,
} from "../../../../packages/core-magistrate-transactions/src/wallet-manager";
import { businessIndexer, MagistrateIndex } from "../../../../packages/core-magistrate-transactions/src/wallet-manager";
import {
bridgechainRegistrationAsset1,
bridgechainRegistrationAsset2,
Expand Down Expand Up @@ -76,7 +72,6 @@ describe("Bridgechain update handler", () => {

walletManager = new Wallets.WalletManager();
walletManager.registerIndex(MagistrateIndex.Businesses, businessIndexer);
walletManager.registerIndex(MagistrateIndex.Bridgechains, bridgechainIndexer);

senderWallet = new Wallets.Wallet("ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo");
senderWallet.balance = Utils.BigNumber.make("500000000000000");
Expand Down
11 changes: 0 additions & 11 deletions packages/core-api/src/handlers/bridgechains/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,6 @@ export class BridgechainController extends Controller {
}
}

public async show(request: Hapi.Request, h: Hapi.ResponseToolkit) {
try {
// @ts-ignore
const data = await request.server.methods.v2.bridgechains.show(request);

return super.respondWithCache(data, h);
} catch (error) {
return Boom.badImplementation(error);
}
}

public async search(request: Hapi.Request, h: Hapi.ResponseToolkit) {
try {
// @ts-ignore
Expand Down
16 changes: 1 addition & 15 deletions packages/core-api/src/handlers/bridgechains/methods.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { app } from "@arkecosystem/core-container";
import { Database } from "@arkecosystem/core-interfaces";
import Boom from "@hapi/boom";
import { ServerCache } from "../../services";
import { paginate, respondWithResource, toPagination } from "../utils";
import { paginate, toPagination } from "../utils";

const databaseService = app.resolvePlugin<Database.IDatabaseService>("database");

Expand All @@ -15,18 +14,6 @@ const index = async request => {
return toPagination(bridgechains, "bridgechain");
};

const show = async request => {
const bridgechain = databaseService.wallets.search(Database.SearchScope.Bridgechains, {
genesisHash: request.params.id,
}).rows[0];

if (!bridgechain) {
return Boom.notFound("Bridgechain not found");
}

return respondWithResource(bridgechain, "bridgechain");
};

const search = async request => {
const bridgechains = databaseService.wallets.search(Database.SearchScope.Bridgechains, {
...request.payload,
Expand All @@ -43,7 +30,6 @@ export const registerMethods = server => {
...request.query,
...paginate(request),
}))
.method("v2.bridgechains.show", show, 8, request => ({ id: request.params.id }))
.method("v2.bridgechains.search", search, 30, request => ({
...request.payload,
...request.query,
Expand Down
9 changes: 0 additions & 9 deletions packages/core-api/src/handlers/bridgechains/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,6 @@ export const registerRoutes = (server: Hapi.Server): void => {
},
});

server.route({
method: "GET",
path: "/bridgechains/{id}",
handler: controller.show,
options: {
validate: Schema.show,
},
});

server.route({
method: "POST",
path: "/bridgechains/search",
Expand Down
8 changes: 0 additions & 8 deletions packages/core-api/src/handlers/bridgechains/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ export const index: object = {
},
};

export const show: object = {
params: {
id: Joi.string()
.hex()
.length(64), // id is genesisHash
},
};

export const search: object = {
query: {
...pagination,
Expand Down
11 changes: 11 additions & 0 deletions packages/core-api/src/handlers/businesses/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ export class BusinessController extends Controller {
}
}

public async bridgechain(request: Hapi.Request, h: Hapi.ResponseToolkit) {
try {
// @ts-ignore
const data = await request.server.methods.v2.businesses.bridgechain(request);

return super.respondWithCache(data, h);
} catch (error) {
return Boom.badImplementation(error);
}
}

public async search(request: Hapi.Request, h: Hapi.ResponseToolkit) {
try {
// @ts-ignore
Expand Down
19 changes: 19 additions & 0 deletions packages/core-api/src/handlers/businesses/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ const bridgechains = async request => {
return toPagination(bridgechains, "bridgechain");
};

const bridgechain = async request => {
const wallet = databaseService.wallets.findById(Database.SearchScope.Wallets, request.params.businessId);

if (!wallet || !wallet.hasAttribute("business")) {
return Boom.notFound("Business not found");
}

const bridgechains = wallet.getAttribute("business.bridgechains");
if (!bridgechains || !bridgechains[request.params.bridgechainId]) {
return Boom.notFound("Bridgechain not found");
}

return respondWithResource(bridgechains[request.params.bridgechainId], "bridgechain");
};

const search = async request => {
const businesses = databaseService.wallets.search(Database.SearchScope.Businesses, {
...request.payload,
Expand All @@ -78,6 +93,10 @@ export const registerMethods = server => {
...request.query,
...paginate(request),
}))
.method("v2.businesses.bridgechain", bridgechain, 8, request => ({
businessId: request.params.businessId,
bridgechainId: request.params.bridgechainId,
}))
.method("v2.businesses.search", search, 30, request => ({
...request.payload,
...request.query,
Expand Down
9 changes: 9 additions & 0 deletions packages/core-api/src/handlers/businesses/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ export const registerRoutes = (server: Hapi.Server): void => {
},
});

server.route({
method: "GET",
path: "/businesses/{businessId}/bridgechains/{bridgechainId}",
handler: controller.bridgechain,
options: {
validate: Schema.bridgechain,
},
});

server.route({
method: "POST",
path: "/businesses/search",
Expand Down
11 changes: 10 additions & 1 deletion packages/core-api/src/handlers/businesses/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const show: object = {
},
query: {
transform: Joi.bool().default(true),
}
},
};

export const bridgechains: object = {
Expand All @@ -36,6 +36,15 @@ export const bridgechains: object = {
},
};

export const bridgechain: object = {
params: {
businessId: walletId,
bridgechainId: Joi.string()
.hex()
.length(64), // genesisHash
},
};

export const search: object = {
query: {
...pagination,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,22 +263,25 @@ export class WalletsBusinessRepository implements Database.IWalletsBusinessRepos
};

const entries: any[] = this.databaseServiceProvider()
.walletManager.getIndex("bridgechains")
.entries()
.reduce((acc, [genesisHash, wallet]) => {
const bridgechains: any[] = wallet.getAttribute("business.bridgechains");
if (bridgechains && bridgechains[genesisHash]) {
const bridgechain: any = bridgechains[genesisHash];
.walletManager.getIndex("businesses")
.values()
.reduce((acc, wallet) => {
const bridgechains: Record<
string,
{
bridgechainAsset: object;
resigned?: boolean;
}
> = wallet.getAttribute("business.bridgechains") || {};

const bridgechainData = {
acc.push(
...Object.values(bridgechains).map(bridgechain => ({
publicKey: wallet.publicKey,
address: wallet.address,
...bridgechain.bridgechainAsset,
isResigned: !!bridgechain.resigned,
};

acc.push(bridgechainData);
}
})),
);

return acc;
}, []);
Expand Down
Loading

0 comments on commit 29019ce

Please sign in to comment.