Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/bitcore-node/src/models/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export class BlockModel extends BaseModel<IBlock> {
const prevBlock = await this.collection.findOne({ chain, network, hash: header.prevHash });
if (prevBlock) {
localTip = prevBlock;
this.updateCachedChainTip({chain, network, block: prevBlock})
this.updateCachedChainTip({ chain, network, block: prevBlock });
} else {
delete this.chainTips[chain][network];
logger.error(`Previous block isn't in the DB need to roll back until we have a block in common`);
Expand Down
2 changes: 2 additions & 0 deletions packages/bitcore-node/src/services/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ export class EventService {
if (blockEvent) {
const block = <IEvent.BlockEvent>blockEvent.payload;
this.blockEvent.emit('block', block);
console.log('EVENT::Emitting block');
lastBlockUpdate = new Date();
console.log('Updated last block seen', lastBlockUpdate);
}
}
if (!this.stopped) {
Expand Down
151 changes: 41 additions & 110 deletions packages/bitcore-node/test/integration/websocket.integration.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { expect } from 'chai';
import { resetDatabase } from '../helpers';
import { AsyncRPC } from '../../src/rpc';
import { BlockStorage } from '../../src/models/block';
import { expect } from 'chai';
import io = require('socket.io-client');
import config from '../../src/config';
import { P2pWorker } from '../../src/services/p2p';
import { Event } from '../../src/services/event';
import { Api } from '../../src/services/api';

const wait = time => new Promise(resolve => setTimeout(resolve, time));
const chain = 'BTC';
const network = 'regtest';
const chainConfig = config.chains[chain][network];
const creds = chainConfig.rpc;
const rpc = new AsyncRPC(creds.username, creds.password, creds.host, creds.port);
let anAddress;

function getSocket() {
const socket = io.connect(
Expand All @@ -25,152 +22,86 @@ function getSocket() {
}

let p2pWorker: P2pWorker;
let socket = getSocket();

describe('Websockets', function() {
this.timeout(180000);

before(async () => {
await resetDatabase();
await Event.start();
await Api.start();
});

beforeEach(() => {
after(async () => {
await Event.stop();
await Api.stop();
});

beforeEach(async () => {
socket = getSocket();
socket.on('connect', () => {
console.log('Socket connected');
socket.emit('room', '/BTC/regtest/inv');
});
p2pWorker = new P2pWorker({
chain,
network,
chainConfig
});
p2pWorker.start();
if (p2pWorker.isSyncing) {
await p2pWorker.syncDone();
}
});

afterEach(async () => {
try {
await p2pWorker.stop();
await socket.disconnect();
} catch (e) {
console.log('Error stopping p2p worker');
}
});

it('should get a new block when one is generated', async () => {
await p2pWorker.start();

anAddress = await rpc.getnewaddress('');
await rpc.call('generatetoaddress', [5, anAddress]);
await p2pWorker.syncDone();
const beforeGenTip = await BlockStorage.getLocalTip({ chain, network });
expect(beforeGenTip).to.not.eq(null);

if (beforeGenTip && beforeGenTip.height && beforeGenTip.height < 100) {
await rpc.call('generatetoaddress', [100, anAddress]);
}
await rpc.call('generatetoaddress', [1, anAddress]);
await p2pWorker.syncDone();
await wait(1000);
const afterGenTip = await BlockStorage.getLocalTip({ chain, network });
expect(afterGenTip).to.not.eq(null);

if (beforeGenTip != null && afterGenTip != null) {
expect(beforeGenTip.height).to.be.lt(afterGenTip.height);
}
});

it('should get a websocket event when a block is added', async () => {
await Event.start();
await Api.start();

p2pWorker = new P2pWorker({
chain,
network,
chainConfig
});

let hasSeenABlockEvent = false;

const socket = getSocket();
let sawEvents = new Promise(resolve => {
socket.on('connect', () => {
socket.emit('room', '/BTC/regtest/inv');
});
socket.on('block', () => {
hasSeenABlockEvent = true;
resolve();
});
});

await p2pWorker.start();
await rpc.call('generatetoaddress', [1, anAddress]);
await sawEvents;
await p2pWorker.stop();
await socket.disconnect();

expect(hasSeenABlockEvent).to.be.eq(true);
});

it('should get a mempool tx and coin when mempool event, senttoaddress, occurs', async () => {
p2pWorker = new P2pWorker({ chain, network, chainConfig });

it('should get websocket events', async () => {
let hasSeenTxEvent = false;
let hasSeenBlockEvent = false;
let hasSeenCoinEvent = false;

const socket = getSocket();
const anAddress = await rpc.getnewaddress('');
let sawEvents = new Promise(resolve => {
socket.on('connect', () => {
socket.emit('room', '/BTC/regtest/inv');
});
socket.on('tx', () => {
hasSeenTxEvent = true;
if (hasSeenTxEvent && hasSeenCoinEvent) {
resolve();
}
});
socket.on('coin', () => {
hasSeenCoinEvent = true;
if (hasSeenTxEvent && hasSeenCoinEvent) {
socket.on('block', () => {
hasSeenBlockEvent = true;
console.log('Block event received');
if (hasSeenTxEvent && hasSeenCoinEvent && hasSeenBlockEvent) {
resolve();
}
});
});
await p2pWorker.start();
await rpc.sendtoaddress('2MuYKLUaKCenkEpwPkWUwYpBoDBNA2dgY3t', 0.1);
await sawEvents;

await p2pWorker.stop();
await socket.disconnect();

expect([hasSeenTxEvent, hasSeenCoinEvent]).to.deep.eq([true, true]);
});

it('should get a mempool event while syncing', async () => {
p2pWorker = new P2pWorker({ chain, network, chainConfig });

let hasSeenTxEvent = false;
let hasSeenCoinEvent = false;

const socket = getSocket();
let sawEvents = new Promise(resolve => {
socket.on('connect', () => {
socket.emit('room', '/BTC/regtest/inv');
});
socket.on('tx', () => {
hasSeenTxEvent = true;
if (hasSeenTxEvent && hasSeenCoinEvent) {
console.log('Transaction event received');
if (hasSeenTxEvent && hasSeenCoinEvent && hasSeenBlockEvent) {
resolve();
}
});
socket.on('coin', () => {
hasSeenCoinEvent = true;
if (hasSeenTxEvent && hasSeenCoinEvent) {
console.log('Coin event received');
if (hasSeenTxEvent && hasSeenCoinEvent && hasSeenBlockEvent) {
resolve();
}
});
});
await p2pWorker.start();
await wait(3000);
p2pWorker.sync();
p2pWorker.isSyncing = true;
console.log('Generating 100 blocks');
await rpc.call('generatetoaddress', [101, anAddress]);
await p2pWorker.syncDone();
console.log('Sync done, generating new block');
await rpc.call('generatetoaddress', [1, anAddress]);
console.log('Sending bitcoin');
await rpc.sendtoaddress('2MuYKLUaKCenkEpwPkWUwYpBoDBNA2dgY3t', 0.1);
await sawEvents;

await p2pWorker.stop();
await socket.disconnect();

expect([hasSeenTxEvent, hasSeenCoinEvent]).to.deep.eq([true, true]);
expect(hasSeenBlockEvent).to.equal(true);
expect(hasSeenTxEvent).to.equal(true);
expect(hasSeenCoinEvent).to.equal(true);
});
});