diff --git a/src/database/AcebaseClient.ts b/src/database/AcebaseClient.ts index b91c4c8..731277b 100644 --- a/src/database/AcebaseClient.ts +++ b/src/database/AcebaseClient.ts @@ -61,6 +61,10 @@ export class AceBaseClient implements Database { } async addOrder(indexedOrder: IndexedOrder): Promise { + await this.refOrders.query() + .filter('order/signer/wallet', '==', indexedOrder.order.signer.wallet) + .filter('order/signer/id', '==', indexedOrder.order.signer.id) + .remove(); await this.refOrders.push(indexedOrder); this.addToken(indexedOrder.order.signer.token) this.addToken(indexedOrder.order.sender.token) diff --git a/src/database/InMemoryDatabase.ts b/src/database/InMemoryDatabase.ts index 072d36f..435bfba 100644 --- a/src/database/InMemoryDatabase.ts +++ b/src/database/InMemoryDatabase.ts @@ -179,7 +179,12 @@ export class InMemoryDatabase implements Database { } ////////////////////////////// Non ERC20 - addOrder(indexedOrder: IndexedOrder): Promise { + async addOrder(indexedOrder: IndexedOrder): Promise { + const ordersToDelete = await this.findOrders((order: DbOrder) => { + return order.signer.wallet === indexedOrder.order.signer.wallet && order.signer.id === indexedOrder.order.signer.id + }) + this.deleteOrders(ordersToDelete) + this.orderDatabase[indexedOrder.hash!] = indexedOrder; this.addToken(indexedOrder.order.signer.token) this.addToken(indexedOrder.order.sender.token) @@ -193,17 +198,32 @@ export class InMemoryDatabase implements Database { return Promise.resolve(); } - deleteOrder(nonce: number, signerWallet: string): Promise { - const orderToDelete = Object.values(this.orderDatabase).find((indexedOrder) => { - const order = indexedOrder.order as DbOrder + async deleteOrder(nonce: number, signerWallet: string): Promise { + const ordersToDelete = await this.findOrders((order: DbOrder) => { return order.nonce === nonce && order.signer.wallet === signerWallet - }); - if (orderToDelete && orderToDelete.hash) { - delete this.orderDatabase[orderToDelete.hash]; - } + }) + this.deleteOrders(ordersToDelete) return Promise.resolve(); } + private deleteOrders(orders: IndexedOrder[]) { + if (orders && orders.length > 0) { + orders.forEach(orderDb => { + if (orderDb.hash) { + delete this.orderDatabase[orderDb.hash]; + } + }) + } + } + + private findOrders(predicate: Function): Promise[]> { + const orders = Object.values(this.orderDatabase).filter((indexedOrder) => { + const order = indexedOrder.order as DbOrder + return predicate(order) + }); + return Promise.resolve(orders); + } + deleteExpiredOrder(timestampInSeconds: number): Promise { const hashToDelete: string[] = Object.keys(this.orderDatabase).filter((key: string) => { return this.orderDatabase[key].order.expiry < timestampInSeconds; diff --git a/src/database/__tests__/Database.test.ts b/src/database/__tests__/Database.test.ts index 0a6b345..1ebd4a5 100644 --- a/src/database/__tests__/Database.test.ts +++ b/src/database/__tests__/Database.test.ts @@ -150,6 +150,13 @@ describe("Database implementations", () => { }) }); + describe("Specific Order", () => { + describe("pair signerwallet-tokenId should be unique", () => { + test("inMemoryDb", async () => { await pairSignerwalletTokenIDIsUnique(inMemoryDatabase); }); + test("acebaseDb", async () => { await pairSignerwalletTokenIDIsUnique(acebaseClient); }); + }) + }); + async function getOrdersERC20By(db: Database) { const dbOrder1: DbOrderERC20 = { nonce: 123, @@ -841,4 +848,29 @@ describe("Database implementations", () => { expect(hash).toBe("86903491dd10421ee4bc866341c9852e18b296d429ed1fdc9fc9c30701d6d8cd"); return Promise.resolve(); } + + async function pairSignerwalletTokenIDIsUnique(db: Database) { + const indexedOrderToOverwrite = forgeIndexedOrder(addedOn, expiryDate, "a_hash"); + const indexedOrder = forgeIndexedOrder(addedOn, expiryDate, "another_hash"); + indexedOrder.order.signer.amount = "100000003" + const expectedIndexedOrder = forgeIndexedOrderResponse(addedOn, expiryDate, "another_hash"); + expectedIndexedOrder.order.signer.amount = "100000003" + + await db.addOrder(indexedOrderToOverwrite); + await db.addOrder(indexedOrder); + + const removedOrder = await db.getOrder("a_hash"); + const existingOrder = await db.getOrder("another_hash"); + + expect(removedOrder.pagination.total).toBe(0) + expect(existingOrder).toEqual({ + orders: { another_hash: expectedIndexedOrder }, + pagination: { + limit: 1, + offset: 0, + total: 1, + }, + }); + return Promise.resolve(); + } }); \ No newline at end of file