UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

250 lines 11.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const config_1 = __importDefault(require("../../src/config")); const block_1 = require("../../src/models/block"); const coin_1 = require("../../src/models/coin"); const transaction_1 = require("../../src/models/transaction"); const p2p_1 = require("../../src/modules/bitcoin/p2p"); const VerificationPeer_1 = require("../../src/modules/bitcoin/VerificationPeer"); const rpc_1 = require("../../src/rpc"); const config_2 = require("../../src/services/config"); const utils_1 = require("../../src/utils"); const helpers_1 = require("../helpers"); const integration_1 = require("../helpers/integration"); const chain = 'BTC'; const network = 'regtest'; const address = '2MuYKLUaKCenkEpwPkWUwYpBoDBNA2dgY3t'; const chainConfig = config_1.default.chains[chain][network]; const creds = chainConfig.rpc; const rpc = new rpc_1.AsyncRPC(creds.username, creds.password, creds.host, creds.port); async function sendBitcoin() { try { await rpc.sendtoaddress(address, 0.1); console.log('Sending'); } catch (e) { // Handle insufficent balance issues console.log('Generating blocks'); const ourAddress = await rpc.getnewaddress(''); await rpc.call('generatetoaddress', [130, ourAddress]); await (0, utils_1.wait)(5000); console.log('Sending after generating'); await rpc.sendtoaddress(address, 0.1); } } function addBlock1() { return block_1.BitcoinBlockStorage.collection.insertOne({ chain, network, height: 8976158, hash: '0x9997699519d116dfa89256d0f6ebd1737db13adca583dc80dbd533d90083961c', version: 100, merkleRoot: 'a2262b524615b6d2f409784ceff898fd46bdde6a584269788c41f26ac4b4919e', time: new Date(1526326784), timeNormalized: new Date(1526326784), transactionCount: 1, reward: 50, nonce: 3, previousBlockHash: '64bfb3eda276ae4ae5b64d9e36c9c0b629bc767fb7ae66f9d55d2c5c8103a929', nextBlockHash: '0xddae2bf21fb5836dec837671afd7bea1cc49d7111462e803ed3efc10570f1858', size: 264, bits: parseInt('207fffff', 16), processed: true }); } function addTx() { return transaction_1.TransactionStorage.collection.insertOne({ chain, network, txid: '0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098', blockHash: '0x9997699519d116dfa89256d0f6ebd1737db13adca583dc80dbd533d90083961c', blockHeight: 8976158, blockTime: new Date('2009-01-09T02:54:25.000Z'), blockTimeNormalized: new Date('2009-01-09T02:54:25.000Z'), coinbase: true, fee: 0, inputCount: 1, locktime: 0, outputCount: 1, size: 134, value: 5000000000.0, wallets: [] }); } function addCoin() { return coin_1.CoinStorage.collection.insertOne({ chain, network, mintIndex: 0, mintTxid: '0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098', address: '12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX', coinbase: true, mintHeight: 1, script: Buffer.from('QQSWtTjoU1GccmoskeYewRYArhOQgTpifGb7i+eUe+Y8Utp1iTeVFdTgpgT4FBeB5iKUchFmv2Iec6gsvyNCyFjurA=='), spentHeight: -2, spentTxid: '', value: 5000000000.0, wallets: [] }); } describe('VerificationPeer', function () { const suite = this; this.timeout(500000); before(integration_1.intBeforeHelper); after(async () => (0, integration_1.intAfterHelper)(suite)); beforeEach(async () => { await (0, helpers_1.resetDatabase)(); }); it('should not save any mempoool transactions', async () => { const chainConfig = config_2.Config.chainConfig({ chain, network }); const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); const sawTx = new Promise(r => { worker.events.on('transaction', r); }); await sendBitcoin(); await sawTx; const txCount = await transaction_1.TransactionStorage.collection.countDocuments({ chain, network }); (0, chai_1.expect)(txCount).to.be.eq(0); worker.disconnect(); }); it('should save any mempoool transactions', async () => { const chainConfig = config_2.Config.chainConfig({ chain, network }); const worker = new p2p_1.BitcoinP2PWorker({ chain, network, chainConfig }); worker.isSyncingNode = true; worker.isSyncing = true; await worker.connect(); const sawTx = new Promise(r => { worker.events.on('transaction', r); }); await sendBitcoin(); await sawTx; const txCount = await transaction_1.TransactionStorage.collection.countDocuments({ chain, network }); (0, chai_1.expect)(txCount).to.be.gt(0); worker.disconnect(); }); it('should detect a fault in a series of blocks', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addBlock1(); await addTx(); await addCoin(); await block_1.BitcoinBlockStorage.collection.updateOne({ hash: '0x9997699519d116dfa89256d0f6ebd1737db13adca583dc80dbd533d90083961c' }, { $unset: { nextBlockHash: '' } }); const tip = 8976159; const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == false); (0, chai_1.expect)(verified.errors.length).to.eq(1); (0, chai_1.expect)(verified.errors[0].type).to.eq('CORRUPTED_BLOCK'); (0, chai_1.expect)(verified.errors[0].payload.txCount).to.eq(1); (0, chai_1.expect)(verified.errors[0].payload.foundTxs).to.eq(1); await worker.disconnect(); }); it('should detect a missing transaction', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addBlock1(); await addCoin(); const tip = 8976159; const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == false); (0, chai_1.expect)(verified.errors.length).to.eq(1); (0, chai_1.expect)(verified.errors[0].type).to.eq('CORRUPTED_BLOCK'); (0, chai_1.expect)(verified.errors[0].payload.txCount).to.eq(1); (0, chai_1.expect)(verified.errors[0].payload.foundTxs).to.eq(0); await worker.disconnect(); }); it('should detect a dupe transaction', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addBlock1(); await addTx(); await addTx(); await addCoin(); const tip = 8976159; const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == false); (0, chai_1.expect)(verified.errors.length).to.eq(2); (0, chai_1.expect)(verified.errors[0].type).to.eq('CORRUPTED_BLOCK'); (0, chai_1.expect)(verified.errors[0].payload.txCount).to.eq(1); (0, chai_1.expect)(verified.errors[0].payload.foundTxs).to.eq(2); (0, chai_1.expect)(verified.errors[1].type).to.eq('DUPE_TRANSACTION'); (0, chai_1.expect)(verified.errors[1].payload.tx.txid).to.eq('0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098'); await worker.disconnect(); }); it('should detect a missing transaction output', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addBlock1(); await addTx(); const tip = 8976159; const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == false); (0, chai_1.expect)(verified.errors.length).to.eq(1); (0, chai_1.expect)(verified.errors[0].type).to.eq('MISSING_COIN_FOR_TXID'); (0, chai_1.expect)(verified.errors[0].payload.txid).to.eq('0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098'); await worker.disconnect(); }); it('should detect a dupe transaction output', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addBlock1(); await addTx(); await addCoin(); await addCoin(); const tip = 8976159; const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == false); (0, chai_1.expect)(verified.errors.length).to.eq(1); (0, chai_1.expect)(verified.errors[0].type).to.eq('DUPE_COIN'); (0, chai_1.expect)(verified.errors[0].payload.coin.mintTxid).to.eq('0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098'); await worker.disconnect(); }); it('should detect a missing block', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addTx(); await addCoin(); const tip = 8976159; const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == false); (0, chai_1.expect)(verified.errors.length).to.eq(1); (0, chai_1.expect)(verified.errors[0].type).to.eq('MISSING_BLOCK'); (0, chai_1.expect)(verified.errors[0].payload.blockNum).to.eq(8976158); await worker.disconnect(); }); it('should detect a dupe block', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addBlock1(); await addBlock1(); await addTx(); await addCoin(); const tip = 8976159; const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == false); (0, chai_1.expect)(verified.errors.length).to.eq(2); (0, chai_1.expect)(verified.errors[0].type).to.eq('DUPE_BLOCKHEIGHT'); (0, chai_1.expect)(verified.errors[0].payload.blockNum).to.eq(8976158); (0, chai_1.expect)(verified.errors[1].type).to.eq('DUPE_BLOCKHASH'); (0, chai_1.expect)(verified.errors[1].payload.blockNum).to.eq(8976158); await worker.disconnect(); }); it('should handle non-linear scanning by ignoring previousBlockHash', async () => { const worker = new VerificationPeer_1.VerificationPeer({ chain, network, chainConfig }); await worker.connect(); await addBlock1(); await addTx(); await addCoin(); await block_1.BitcoinBlockStorage.collection.updateOne({ hash: '0x9997699519d116dfa89256d0f6ebd1737db13adca583dc80dbd533d90083961c' }, { $set: { previousBlockHash: 'abcdefg' } }); const tip = 8976159; await worker.validateDataForBlock(8976154, tip, true); const verified = await worker.validateDataForBlock(8976158, tip, true); (0, chai_1.expect)(verified.success == true); await worker.disconnect(); }); }); //# sourceMappingURL=verification.spec.js.map