Skip to content

Commit

Permalink
feat(storage): #1989: add subaccount filter to getOwnedPositionIds
Browse files Browse the repository at this point in the history
…method
  • Loading branch information
VanishMax committed Jan 28, 2025
1 parent 3b44f94 commit 8d6b007
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 16 deletions.
20 changes: 17 additions & 3 deletions packages/storage/src/indexed-db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ export class IndexedDb implements IndexedDbInterface {
async *getOwnedPositionIds(
positionState: PositionState | undefined,
tradingPair: TradingPair | undefined,
subaccount: AddressIndex | undefined,
) {
yield* new ReadableStream({
start: async cont => {
Expand All @@ -578,7 +579,10 @@ export class IndexedDb implements IndexedDbInterface {
const position = Position.fromJson(cursor.value.position);
if (
(!positionState || positionState.equals(position.state)) &&
(!tradingPair || tradingPair.equals(position.phi?.pair))
(!tradingPair || tradingPair.equals(position.phi?.pair)) &&
(!subaccount ||
(cursor.value.subaccount &&
subaccount.equals(AddressIndex.fromJson(cursor.value.subaccount))))
) {
cont.enqueue(PositionId.fromJson(cursor.value.id));
}
Expand All @@ -589,16 +593,25 @@ export class IndexedDb implements IndexedDbInterface {
});
}

async addPosition(positionId: PositionId, position: Position): Promise<void> {
async addPosition(
positionId: PositionId,
position: Position,
subaccount?: AddressIndex,
): Promise<void> {
assertPositionId(positionId);
const positionRecord = {
id: positionId.toJson() as Jsonified<PositionId>,
position: position.toJson() as Jsonified<Position>,
subaccount: subaccount && (subaccount.toJson() as Jsonified<AddressIndex>),
};
await this.u.update({ table: 'POSITIONS', value: positionRecord });
}

async updatePosition(positionId: PositionId, newState: PositionState): Promise<void> {
async updatePosition(
positionId: PositionId,
newState: PositionState,
subaccount?: AddressIndex,
): Promise<void> {
assertPositionId(positionId);
const key = uint8ArrayToBase64(positionId.inner);
const positionRecord = await this.db.get('POSITIONS', key);
Expand All @@ -615,6 +628,7 @@ export class IndexedDb implements IndexedDbInterface {
value: {
id: positionId.toJson() as Jsonified<PositionId>,
position: position.toJson() as Jsonified<Position>,
subaccount: subaccount ? (subaccount.toJson() as Jsonified<AddressIndex>) : undefined,
},
});
}
Expand Down
4 changes: 4 additions & 0 deletions packages/storage/src/indexed-db/indexed-db.test-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Transaction } from '@penumbra-zone/protobuf/penumbra/core/transaction/v
import type { ScanBlockResult } from '@penumbra-zone/types/state-commitment-tree';
import { base64ToUint8Array } from '@penumbra-zone/types/base64';
import { StateCommitment } from '@penumbra-zone/protobuf/penumbra/crypto/tct/v1/tct_pb';
import { AddressIndex } from '@penumbra-zone/protobuf/penumbra/core/keys/v1/keys_pb';

const hash3312332298 = base64ToUint8Array('JbOzRkf0VKm4eIM0DS27N5igX8jxvPhAMpBWSr2bj/Q=');

Expand Down Expand Up @@ -717,3 +718,6 @@ export const epoch3 = new Epoch({
index: 3n,
startHeight: 300n,
});

export const mainAccount = new AddressIndex({ account: 0 });
export const firstSubaccount = new AddressIndex({ account: 1 });
46 changes: 33 additions & 13 deletions packages/storage/src/indexed-db/indexed-db.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
tradingPairGmGn,
transaction,
transactionId,
mainAccount,
firstSubaccount,
} from './indexed-db.test-data.js';
import { AddressIndex, WalletId } from '@penumbra-zone/protobuf/penumbra/core/keys/v1/keys_pb';
import {
Expand Down Expand Up @@ -496,13 +498,13 @@ describe('IndexedDb', () => {
it('position should be added and their state should change', async () => {
const db = await IndexedDb.initialize({ ...generateInitialProps() });

await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy);
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy, mainAccount);
await db.updatePosition(
positionIdGmPenumbraBuy,
new PositionState({ state: PositionState_PositionStateEnum.CLOSED }),
);
const ownedPositions: PositionId[] = [];
for await (const positionId of db.getOwnedPositionIds(undefined, undefined)) {
for await (const positionId of db.getOwnedPositionIds(undefined, undefined, undefined)) {
ownedPositions.push(positionId as PositionId);
}
expect(ownedPositions.length).toBe(1);
Expand All @@ -521,27 +523,28 @@ describe('IndexedDb', () => {

it('should get all position ids', async () => {
const db = await IndexedDb.initialize({ ...generateInitialProps() });
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy);
await db.addPosition(positionIdGnPenumbraSell, positionGnPenumbraSell);
await db.addPosition(positionIdGmGnSell, positionGmGnSell);
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy, mainAccount);
await db.addPosition(positionIdGnPenumbraSell, positionGnPenumbraSell, mainAccount);
await db.addPosition(positionIdGmGnSell, positionGmGnSell, firstSubaccount);

const ownedPositions: PositionId[] = [];
for await (const positionId of db.getOwnedPositionIds(undefined, undefined)) {
for await (const positionId of db.getOwnedPositionIds(undefined, undefined, undefined)) {
ownedPositions.push(positionId as PositionId);
}
expect(ownedPositions.length).toBe(3);
});

it('should get all position with given position state', async () => {
const db = await IndexedDb.initialize({ ...generateInitialProps() });
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy);
await db.addPosition(positionIdGnPenumbraSell, positionGnPenumbraSell);
await db.addPosition(positionIdGmGnSell, positionGmGnSell);
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy, mainAccount);
await db.addPosition(positionIdGnPenumbraSell, positionGnPenumbraSell, mainAccount);
await db.addPosition(positionIdGmGnSell, positionGmGnSell, firstSubaccount);

const ownedPositions: PositionId[] = [];
for await (const positionId of db.getOwnedPositionIds(
new PositionState({ state: PositionState_PositionStateEnum.CLOSED }),
undefined,
undefined,
)) {
ownedPositions.push(positionId as PositionId);
}
Expand All @@ -550,16 +553,33 @@ describe('IndexedDb', () => {

it('should get all position with given trading pair', async () => {
const db = await IndexedDb.initialize({ ...generateInitialProps() });
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy);
await db.addPosition(positionIdGnPenumbraSell, positionGnPenumbraSell);
await db.addPosition(positionIdGmGnSell, positionGmGnSell);
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy, mainAccount);
await db.addPosition(positionIdGnPenumbraSell, positionGnPenumbraSell, mainAccount);
await db.addPosition(positionIdGmGnSell, positionGmGnSell, firstSubaccount);

const ownedPositions: PositionId[] = [];
for await (const positionId of db.getOwnedPositionIds(undefined, tradingPairGmGn)) {
for await (const positionId of db.getOwnedPositionIds(
undefined,
tradingPairGmGn,
undefined,
)) {
ownedPositions.push(positionId as PositionId);
}
expect(ownedPositions.length).toBe(1);
});

it('should get all position with given subaccount index', async () => {
const db = await IndexedDb.initialize({ ...generateInitialProps() });
await db.addPosition(positionIdGmPenumbraBuy, positionGmPenumbraBuy, mainAccount);
await db.addPosition(positionIdGnPenumbraSell, positionGnPenumbraSell, mainAccount);
await db.addPosition(positionIdGmGnSell, positionGmGnSell, firstSubaccount);

const ownedPositions: PositionId[] = [];
for await (const positionId of db.getOwnedPositionIds(undefined, undefined, mainAccount)) {
ownedPositions.push(positionId as PositionId);
}
expect(ownedPositions.length).toBe(2);
});
});

describe('prices', () => {
Expand Down

0 comments on commit 8d6b007

Please sign in to comment.