diff --git a/test/auction-reorg-test.js b/test/auction-reorg-test.js index 0108bd0a..2b50436e 100644 --- a/test/auction-reorg-test.js +++ b/test/auction-reorg-test.js @@ -12,6 +12,7 @@ const MemWallet = require('./util/memwallet'); const Network = require('../lib/protocol/network'); const rules = require('../lib/covenants/rules'); const {ownership} = require('../lib/covenants/ownership'); +const {CachedStubResolver} = require('./util/stub'); const network = Network.get('regtest'); const {treeInterval} = network.names; @@ -73,6 +74,16 @@ function createNode() { describe('Auction Reorg', function() { this.timeout(20000); + const originalResolver = ownership.Resolver; + + before(() => { + ownership.Resolver = CachedStubResolver; + }); + + after(() => { + ownership.Resolver = originalResolver; + }); + describe('Vickrey Auction Reorg', function() { const node = createNode(); const orig = createNode(); diff --git a/test/auction-test.js b/test/auction-test.js index ac03d05d..6a712bc9 100644 --- a/test/auction-test.js +++ b/test/auction-test.js @@ -9,6 +9,7 @@ const MemWallet = require('./util/memwallet'); const Network = require('../lib/protocol/network'); const rules = require('../lib/covenants/rules'); const {ownership} = require('../lib/covenants/ownership'); +const {CachedStubResolver} = require('./util/stub'); const network = Network.get('regtest'); const GNAME_SIZE = 10; @@ -69,6 +70,16 @@ function createNode() { describe('Auction', function() { this.timeout(15000); + const originalResolver = ownership.Resolver; + + before(() => { + ownership.Resolver = CachedStubResolver; + }); + + after(() => { + ownership.Resolver = originalResolver; + }); + describe('Vickrey Auction', function() { const node = createNode(); const orig = createNode(); diff --git a/test/chain-checkpoints-test.js b/test/chain-checkpoints-test.js index bff0639c..0c26ff4c 100644 --- a/test/chain-checkpoints-test.js +++ b/test/chain-checkpoints-test.js @@ -13,6 +13,7 @@ const Network = require('../lib/protocol/network'); const rules = require('../lib/covenants/rules'); const {Resource} = require('../lib/dns/resource'); const AirdropProof = require('../lib/primitives/airdropproof'); +const {CachedStubResolver} = require('./util/stub'); const network = Network.get('regtest'); @@ -91,8 +92,11 @@ async function mineBlocks(n, label) { } describe('Checkpoints', function() { + const originalResolver = ownership.Resolver; + before(async () => { ownership.ignore = true; + ownership.Resolver = CachedStubResolver; await blocks.open(); await chainGenerator.open(); @@ -105,6 +109,7 @@ describe('Checkpoints', function() { await blocks.close(); ownership.ignore = false; + ownership.Resolver = originalResolver; }); it('should add addrs to miner', async () => { diff --git a/test/chain-icann-lockup-test.js b/test/chain-icann-lockup-test.js index 477624cf..c168afcb 100644 --- a/test/chain-icann-lockup-test.js +++ b/test/chain-icann-lockup-test.js @@ -10,6 +10,7 @@ const chainCommon = require('../lib/blockchain/common'); const {BufferMap} = require('buffer-map'); const {thresholdStates} = chainCommon; const {isReserved, isLockedUp, hashName} = require('../lib/covenants/rules'); +const {CachedStubResolver} = require('./util/stub'); const SOFT_FORK_NAME = 'icannlockup'; @@ -52,6 +53,16 @@ const ACTUAL_RENEWAL_WINDOW = network.names.renewalWindow; describe('BIP9 - ICANN lockup (integration)', function() { this.timeout(20000); + const originalResolver = ownership.Resolver; + + before(() => { + ownership.Resolver = CachedStubResolver; + }); + + after(() => { + ownership.Resolver = originalResolver; + }); + const CUSTOM = [ 'cloudflare', 'nlnetlabs', diff --git a/test/claim-test.js b/test/claim-test.js index 94249111..264394a8 100644 --- a/test/claim-test.js +++ b/test/claim-test.js @@ -9,6 +9,7 @@ const consensus = require('../lib/protocol/consensus'); const {ownership} = require('../lib/covenants/ownership'); const reserved = require('../lib/covenants/reserved'); const {Resource} = require('../lib/dns/resource'); +const {CachedStubResolver} = require('./util/stub'); const network = Network.get('regtest'); @@ -47,15 +48,19 @@ async function mineBlocks(n, addr) { describe('Reserved Name Claims', function() { this.timeout(10000); + const originalResolver = ownership.Resolver; + before(async () => { await node.open(); wallet = await wdb.create(); addr = await wallet.receiveAddress(); + ownership.Resolver = CachedStubResolver; }); after(async () => { await node.close(); + ownership.Resolver = originalResolver; }); // Reset the ownership flag after every test, diff --git a/test/mempool-invalidation-test.js b/test/mempool-invalidation-test.js index 85c27bff..dbaf6dfa 100644 --- a/test/mempool-invalidation-test.js +++ b/test/mempool-invalidation-test.js @@ -9,6 +9,7 @@ const rules = require('../lib/covenants/rules'); const {states} = require('../lib/covenants/namestate'); const {Resource} = require('../lib/dns/resource'); const {forEvent} = require('./util/common'); +const {CachedStubResolver} = require('./util/stub'); const network = Network.get('regtest'); const { @@ -21,6 +22,16 @@ const ACTUAL_CLAIM_PERIOD = claimPeriod; const ACTUAL_RENEWAL_WINDOW = renewalWindow; describe('Mempool Invalidation', function() { + const originalResolver = ownership.Resolver; + + before(() => { + ownership.Resolver = CachedStubResolver; + }); + + after(() => { + ownership.Resolver = originalResolver; + }); + const NAMES = [ // roots 'nl', diff --git a/test/mempool-test.js b/test/mempool-test.js index c193354c..6c8ab73a 100644 --- a/test/mempool-test.js +++ b/test/mempool-test.js @@ -33,6 +33,7 @@ const rules = require('../lib/covenants/rules'); const NameState = require('../lib/covenants/namestate'); const {states} = NameState; const {ownership} = require('../lib/covenants/ownership'); +const {CachedStubResolver} = require('./util/stub'); const ONE_HASH = Buffer.alloc(32, 0x00); ONE_HASH[0] = 0x01; @@ -75,6 +76,16 @@ async function getMockBlock(chain, txs = [], cb = true) { describe('Mempool', function() { this.timeout(5000); + const originalResolver = ownership.Resolver; + + before(() => { + ownership.Resolver = CachedStubResolver; + }); + + after(() => { + ownership.Resolver = originalResolver; + }); + describe('Mempool TXs', function() { let workers, blocks, chain, mempool, wallet; let cachedTX; diff --git a/test/txstart-test.js b/test/txstart-test.js index bc70a4c4..c40d502a 100644 --- a/test/txstart-test.js +++ b/test/txstart-test.js @@ -14,6 +14,7 @@ const Address = require('../lib/primitives/address'); const Script = require('../lib/script/script'); const common = require('../lib/blockchain/common'); const {ownership} = require('../lib/covenants/ownership'); +const {CachedStubResolver} = require('./util/stub'); const VERIFY_NONE = common.flags.VERIFY_NONE; const node = new FullNode({ @@ -49,6 +50,8 @@ describe('Disable TXs', function() { let utxo, lastTX; + const originalResolver = ownership.Resolver; + before(async () => { node.network.txStart = 5; await node.open(); @@ -56,11 +59,13 @@ describe('Disable TXs', function() { // Start with one block for the fakeClaim const block = await node.miner.mineBlock(); assert(await node.chain.add(block)); + ownership.Resolver = CachedStubResolver; }); after(async () => { await node.close(); node.network.txStart = RESET_TXSTART; + ownership.Resolver = originalResolver; }); it('should reject tx from mempool before txStart', async () => { diff --git a/test/util/stub.js b/test/util/stub.js new file mode 100644 index 00000000..95aef072 --- /dev/null +++ b/test/util/stub.js @@ -0,0 +1,85 @@ +'use strict'; + +const assert = require('bsert'); +const path = require('path'); +const {StubResolver, wire} = require('bns'); +const fs = require('bfile'); +const {tmpdir} = require('os'); + +let CACHE = {}; + +/** + * Proxy requests if they are not cached. + */ + +class CachedStubResolver extends StubResolver { + constructor(options) { + super(options); + + this.enabled = true; + this.cacheOnDisk = false; + this.cacheFile = path.join(tmpdir(), 'hsd', 'dns-cache.json'); + + this.loadCacheSync(); + } + + loadCacheSync() { + if (!this.cacheOnDisk) + return; + + if (fs.existsSync(this.cacheFile)) + CACHE = JSON.parse(fs.readFileSync(this.cacheFile, 'utf8')); + } + + saveCacheSync() { + if (!this.cacheOnDisk) + return; + + const stringified = JSON.stringify(CACHE, null, 2); + fs.writeFileSync(this.cacheFile, stringified, 'utf8'); + } + + setCache(qs, res) { + if (!this.enabled) + return; + + assert(qs instanceof wire.Question); + assert(res instanceof wire.Message); + + CACHE[qs.toString()] = res.toString(); + this.saveCacheSync(); + } + + hasCache(qs) { + if (!this.enabled) + return false; + + assert(qs instanceof wire.Question); + + return Boolean(CACHE[qs.toString()]); + } + + getCache(qs) { + if (!this.enabled) + return null; + + assert(qs instanceof wire.Question); + + return wire.Message.fromString(CACHE[qs.toString()]); + } + + async resolve(qs) { + if (this.hasCache(qs)) + return this.getCache(qs); + + const resolved = await super.resolve(qs); + + if (!resolved) + return null; + + this.setCache(qs, resolved); + return resolved; + } +} + +exports.CachedStubResolver = CachedStubResolver;