Skip to content

Commit

Permalink
feat: add batch fn for saveDlcAccepts rocksdb
Browse files Browse the repository at this point in the history
Add saveDlcAccepts to rocksdb specifically for batch funded dlcs
  • Loading branch information
matthewjablack committed Mar 20, 2024
1 parent d456ac8 commit fa85f80
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 3 deletions.
3 changes: 3 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
install:
yarn && yarn bootstrap

bootstrap:
yarn bootstrap

build:
yarn build

Expand Down
26 changes: 25 additions & 1 deletion packages/rocksdb/__tests__/rocksdb-dlc-store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
DlcTransactionsV0,
FundingInputV0,
} from '@node-dlc/messaging';
import { OutPoint } from '@node-lightning/bitcoin';
import { OutPoint, Value } from '@node-lightning/bitcoin';
import { sha256, xor } from '@node-lightning/crypto';
import { expect } from 'chai';

Expand Down Expand Up @@ -211,6 +211,23 @@ describe('RocksdbDlcStore', () => {

const dlcClose = DlcCloseV0.deserialize(dlcCloseHex);

// Batch Dlc Messages

// Increase funding input amount to match minimum collateral for batch
const dlcOfferForBatch = DlcOfferV0.deserialize(dlcOffer.serialize());
(dlcOfferForBatch
.fundingInputs[0] as FundingInputV0).prevTx.outputs[0].value = Value.fromBitcoin(
4,
);

// Increase funding input amount to match minimum collateral for batch
const dlcAcceptForBatch = DlcAcceptV0.deserialize(dlcAccept.serialize());
dlcAcceptForBatch.tempContractId = sha256(dlcOfferForBatch.serialize());
(dlcAcceptForBatch
.fundingInputs[0] as FundingInputV0).prevTx.outputs[0].value = Value.fromBitcoin(
4,
);

before(async () => {
util.rmdir('.testdb');
sut = new RocksdbDlcStore('./.testdb/nested/dir');
Expand Down Expand Up @@ -365,6 +382,13 @@ describe('RocksdbDlcStore', () => {
});
});

describe('save dlc_accepts', () => {
it('should save batch dlc accepts', async () => {
await sut.saveDlcOffer(dlcOfferForBatch);
await sut.saveDlcAccepts([dlcAcceptForBatch, dlcAcceptForBatch]);
});
});

describe('delete dlc_offer', () => {
it('should delete dlc_offer', async () => {
await sut.deleteDlcOffer(contractId);
Expand Down
47 changes: 45 additions & 2 deletions packages/rocksdb/lib/rocksdb-dlc-store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { DlcTxBuilder } from '@node-dlc/core';
import { BatchDlcTxBuilder, DlcTxBuilder } from '@node-dlc/core';
import {
ContractInfo,
ContractInfoV0,
ContractInfoV1,
DlcAcceptV0,
Expand Down Expand Up @@ -257,6 +256,50 @@ export class RocksdbDlcStore extends RocksdbBase {
await this._db.put(key3, contractId);
}

// NOTE: ONLY USE FOR BATCH FUNDED DLCs
public async saveDlcAccepts(dlcAccepts: DlcAcceptV0[]): Promise<void> {
const dlcOffers: DlcOfferV0[] = [];
for (let i = 0; i < dlcAccepts.length; i++) {
const dlcOffer = await this.findDlcOffer(dlcAccepts[i].tempContractId);
dlcOffers.push(dlcOffer);
}
const txBuilder = new BatchDlcTxBuilder(dlcOffers, dlcAccepts);
const tx = txBuilder.buildFundingTransaction();
const fundingTxId = tx.txId.serialize();
const contractIds = dlcAccepts.map((dlcAccepts) =>
xor(fundingTxId, dlcAccepts.tempContractId),
);
for (let i = 0; i < dlcAccepts.length; i++) {
const value = dlcAccepts[i].serialize();
const key = Buffer.concat([
Buffer.from([Prefix.DlcAcceptV0]),
contractIds[i],
]);
await this._db.put(key, value);

// store funding input outpoint reference
for (let i = 0; i < dlcAccepts[i].fundingInputs.length; i++) {
const fundingInput = dlcAccepts[i].fundingInputs[i] as FundingInputV0;

const outpoint = OutPoint.fromString(
`${fundingInput.prevTx.txId.toString()}:${fundingInput.prevTxVout}`,
);

const key2 = Buffer.concat([
Buffer.from([Prefix.Outpoint]),
Buffer.from(outpoint.toString()),
]);
await this._db.put(key2, contractIds[i]);
}

const key3 = Buffer.concat([
Buffer.from([Prefix.TempContractId]),
dlcAccepts[i].tempContractId,
]);
await this._db.put(key3, contractIds[i]);
}
}

public async deleteDlcAccept(contractId: Buffer): Promise<void> {
const key = Buffer.concat([Buffer.from([Prefix.DlcAcceptV0]), contractId]);
await this._db.del(key);
Expand Down

0 comments on commit fa85f80

Please sign in to comment.