@node-dlc/messaging
Version:
DLC Messaging Protocol
179 lines (156 loc) • 9.94 kB
text/typescript
// tslint:disable: no-unused-expression
import { expect } from 'chai';
import sinon from 'sinon';
import { ChainManager } from '../../lib/chain/ChainManager';
import { ChainMemoryStore } from '../../lib/chain/ChainMemoryStore';
import { IChainFilterChainClient } from '../../lib/chain/IChainFilterChainClient';
import { CloseType, DlcTransactions } from '../../lib/messages/DlcTransactions';
import { createFakeLogger } from '../_test-utils';
const fundBlock = {
hash: '61a8eb0296d80f9f173d397b551ceb14aaaacfb91570c0ec6ee96593a5f92847',
height: 2885,
buf: Buffer.from(
'000000200e09e38f56938091e2a85912eb110135d00dc73a9de71ed9d0140eb69cf8876db28a05584986effa2fb6757e00fc6ec14a51655138001b964c9f99adb1af7933a0d58960ffff7f200000000002020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502450b0101ffffffff02182f00000000000017a9140026e31816a85a8b2cddd4bf4c9248d5257ce5b4870000000000000000266a24aa21a9edb7dbaa40b737b2d733fd1fb05d79f43915bbd52e7c774a8932918797c3cb1d4c0120000000000000000000000000000000000000000000000000000000000000000000000000020000000001027d271264eaa899ce808a151b67a05a5e138bc59bff4a81acc606bbcc2054c33a0000000000ffffffff49956aee0f04ebeed5935729a2d6d5dc6abb5342acaa0248090c78b049e4d4e30000000000ffffffff0355a8980400000000220020543ff4768635379e2d3101d97f5a2a5e15d2acba04a6bd1322970241de8c593ce11f530700000000160014dddb7840134737de920ac4337cfd700a94d40ee6f2b1eb0b000000001600141b77056446c159cd6228632173c6117d67ed7df2024730440220733860701aa74b928ff6a2aa6e1f46074b1fe159d0bf98e5b669185cab6f86c9022013ca0c79abffecedeb683be50654f6d757763aea76b1fb70ac08f275c08da9a801210328917c56d06fc4045b0d4e6a0d917e4aea5f950294f95b870ac6c5d8c251e4af0247304402207da0a975df0e98f1d98ced003c2507e6848bbd05323f308f7e38cd1ecc1d12c902202140ec16d368ac52a514d0a84963f550a10e14d68dc2cb36fdaa39d3db2086e10121029f97f9c53bb8664b64346e9ce6340070a0e85396b4f185abef0d7ca23a71753d00000000',
'hex',
),
};
const fundTxid =
'089d8f783b6b68b35d50de766cb7847721db8f3a1a529b77abf15d0cb2edbeb2';
const closeBlock = {
hash: '5293da71b1c64a177c6d9cef747ba44c7e05b476663ba1c2af423ee15077287a',
height: 2886,
buf: Buffer.from(
'000000204728f9a59365e96eecc07015b9cfaaaa14eb1c557b393d179f0fd89602eba8616876e849e696d62f8ac71296f826b8b59b6cca46a9f97f220fe8c9037e3ae119a0d58960ffff7f200100000002020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502460b0101ffffffff02e42b00000000000017a9140026e31816a85a8b2cddd4bf4c9248d5257ce5b4870000000000000000266a24aa21a9edbbb084f6f98a556b730069c62876e38d8a8f85d7ba6ce47da3010c8a66013663012000000000000000000000000000000000000000000000000000000000000000000000000002000000000101b2beedb20c5df1ab779b521a3a8fdb217784b76c76de505db3686b3b788f9d080000000000ffffffff02e0739804000000001600144b71dd93c0727574dfd8403ed5f375922c6e3813d12d000000000000160014cc6f10246659b11e40bc8c7d346f43aae79cf2d7040047304402200eeb1c563649678dd57d5a028904673fcd8b262ecd7e59d713b39a12b4165c4802200e6c059dad137fcbf874b232bbc2b231f70d920ec0f3b306ea48bdcd13e6905001483045022100cf6359e4667e413da700a1ffe753dbe298c5cc67814286dd97444758dddda8220220786eb172c61eb20a7d4e8c3117cac23e9f8dd00a3330e9990e60af8d6a3247c501475221031a609094877c033c4e265879cac8dbd86678e30123a113c62f9c5a9d5452a381210367e32f0675eb51b233cb015ee98218b95d70de19390c30bafd7e82c5babafcb452ae00000000',
'hex',
),
};
const closeTxid =
'dfbc85071da98db1b4e82d5fe0623092eeebf45d1d1a36f963c5299dc4ff2b5a';
function createFakeChainClient() {
return {
getBlockchainInfo: sinon.stub().returns({
blocks: closeBlock.height,
bestblockhash: closeBlock.hash,
}),
getBlockHash: sinon.stub().returns(closeBlock.hash),
getBlock: sinon.stub().returns({
hash: closeBlock.hash,
height: closeBlock.height,
}),
getRawBlock: sinon.stub().returns(closeBlock.buf),
getTransaction: sinon.stub(),
getUtxo: sinon.stub(),
waitForSync: sinon.stub(),
};
}
function createFakeChainClientNoCloseTx() {
return {
getBlockchainInfo: sinon.stub().returns({
blocks: fundBlock.height,
bestblockhash: fundBlock.hash,
}),
getBlockHash: sinon.stub().returns(fundBlock.hash),
getBlock: sinon.stub().returns({
hash: fundBlock.hash,
height: fundBlock.height,
}),
getRawBlock: sinon.stub().returns(fundBlock.buf),
getTransaction: sinon.stub().returns({
txid: fundTxid,
blockhash: fundBlock.hash,
}),
getUtxo: sinon.stub().returns({
confirmations: '1',
}),
waitForSync: sinon.stub(),
};
}
describe('ChainManager', () => {
let sut: ChainManager;
let dlcStore: ChainMemoryStore;
let chainClient: IChainFilterChainClient;
beforeEach(() => {
dlcStore = new ChainMemoryStore();
chainClient = createFakeChainClient();
sut = new ChainManager(createFakeLogger(), chainClient, dlcStore);
});
describe('.start()', () => {
describe('no history', () => {
it('should restore block height to 0', async () => {
await sut.start();
expect(sut.blockHeight).to.equal(0);
});
});
describe('with history', () => {
beforeEach(async () => {
const dlcTxs = DlcTransactions.deserialize(
Buffer.from(
'ef2e5beedf007afc0528fadd297df3ad2568ab23b777cc1f1cbc36ee42aad5fdc83b00c502000000027d271264eaa899ce808a151b67a05a5e138bc59bff4a81acc606bbcc2054c33a0000000000ffffffff49956aee0f04ebeed5935729a2d6d5dc6abb5342acaa0248090c78b049e4d4e30000000000ffffffff0355a8980400000000220020543ff4768635379e2d3101d97f5a2a5e15d2acba04a6bd1322970241de8c593ce11f530700000000160014dddb7840134737de920ac4337cfd700a94d40ee6f2b1eb0b000000001600141b77056446c159cd6228632173c6117d67ed7df2000000000000000061a8eb0296d80f9f173d397b551ceb14aaaacfb91570c0ec6ee96593a5f9284700000b450000000000710200000001b2beedb20c5df1ab779b521a3a8fdb217784b76c76de505db3686b3b788f9d080000000000feffffff02e1999804000000001600144b71dd93c0727574dfd8403ed5f375922c6e3813d007000000000000160014cc6f10246659b11e40bc8c7d346f43aae79cf2d78c1064600100710200000001b2beedb20c5df1ab779b521a3a8fdb217784b76c76de505db3686b3b788f9d080000000000ffffffff02e0739804000000001600144b71dd93c0727574dfd8403ed5f375922c6e3813d12d000000000000160014cc6f10246659b11e40bc8c7d346f43aae79cf2d70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
'hex',
),
);
await dlcStore.saveDlcTransactions(dlcTxs);
});
it("should restore to highest dlc's block", async () => {
await sut.start();
expect(sut.blockHeight).to.equal(2886);
});
it('should include close epoch', async () => {
await sut.start();
const results = await dlcStore.findDlcTransactionsList();
expect(results.length).to.equal(1);
expect(results[0].closeEpoch.hash.toString('hex')).to.equal(
closeBlock.hash,
);
expect(results[0].closeEpoch.height).to.equal(closeBlock.height);
expect(results[0].closeType).to.equal(CloseType.ExecuteClose);
expect(results[0].closeBroadcastHeight).to.equal(closeBlock.height - 1);
expect(results[0].closeTxHash).to.deep.equal(
Buffer.from(closeTxid, 'hex'),
);
});
});
describe('with sync requird', () => {
it('waits for chain sync', async () => {
// delay sync for 100 s
chainClient.waitForSync = () =>
new Promise((resolve) => setTimeout(resolve, 100));
sut = new ChainManager(createFakeLogger(), chainClient, dlcStore);
const start = Date.now();
await sut.start();
const end = Date.now();
// start should be delayed by 100ms
expect(end - start).to.be.gte(100);
});
});
describe('with history but no close tx', () => {
beforeEach(async () => {
sut = new ChainManager(
createFakeLogger(),
createFakeChainClientNoCloseTx(),
dlcStore,
);
const dlcTxs = DlcTransactions.deserialize(
Buffer.from(
'ef2e5beedf007afc0528fadd297df3ad2568ab23b777cc1f1cbc36ee42aad5fdc83b00c502000000027d271264eaa899ce808a151b67a05a5e138bc59bff4a81acc606bbcc2054c33a0000000000ffffffff49956aee0f04ebeed5935729a2d6d5dc6abb5342acaa0248090c78b049e4d4e30000000000ffffffff0355a8980400000000220020543ff4768635379e2d3101d97f5a2a5e15d2acba04a6bd1322970241de8c593ce11f530700000000160014dddb7840134737de920ac4337cfd700a94d40ee6f2b1eb0b000000001600141b77056446c159cd6228632173c6117d67ed7df2000000000000000061a8eb0296d80f9f173d397b551ceb14aaaacfb91570c0ec6ee96593a5f9284700000b450000000000710200000001b2beedb20c5df1ab779b521a3a8fdb217784b76c76de505db3686b3b788f9d080000000000feffffff02e1999804000000001600144b71dd93c0727574dfd8403ed5f375922c6e3813d007000000000000160014cc6f10246659b11e40bc8c7d346f43aae79cf2d78c1064600100710200000001b2beedb20c5df1ab779b521a3a8fdb217784b76c76de505db3686b3b788f9d080000000000ffffffff02e0739804000000001600144b71dd93c0727574dfd8403ed5f375922c6e3813d12d000000000000160014cc6f10246659b11e40bc8c7d346f43aae79cf2d70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
'hex',
),
);
await dlcStore.saveDlcTransactions(dlcTxs);
});
it("should restore to highest dlc's block", async () => {
await sut.start();
expect(sut.blockHeight).to.equal(fundBlock.height);
});
it('should include fund epoch', async () => {
await sut.start();
const results = await dlcStore.findDlcTransactionsList();
expect(results.length).to.equal(1);
expect(results[0].fundEpoch.hash.toString('hex')).to.equal(
fundBlock.hash,
);
expect(results[0].fundEpoch.height).to.equal(fundBlock.height);
});
});
});
});