UNPKG

@kadena/hardhat-chainweb

Version:
153 lines 5.29 kB
"use strict"; /* *************************************************************************** */ /* Chain */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Chain = void 0; const async_lock_1 = __importDefault(require("async-lock")); const network_contracts_js_1 = require("./network-contracts.js"); const logger_js_1 = require("./logger.js"); const create_hardhat_provider_js_1 = require("./create-hardhat-provider.js"); const lock = new async_lock_1.default(); class Chain { get provider() { if (!this._provider) { throw new Error('Provider is not initialized'); } return this._provider; } set adjacents(adjacents) { this._adjacents = adjacents; } get adjacents() { if (this._adjacents === null) { throw new Error('Chain is not part of a network'); } return this._adjacents; } constructor(config, logging = 'info') { this.logging = logging; const cid = config.chainwebChainId; this.config = config; this.logger = { info: (msg) => logging !== 'none' ? (0, logger_js_1.logInfo)(logger_js_1.COLOR_PALETTE[cid % 6], cid, msg) : null, error: (msg) => logging !== 'none' ? (0, logger_js_1.logError)(logger_js_1.COLOR_PALETTE[cid % 6], cid, msg) : null, }; // set when the chain is added to the chainweb this._adjacents = null; // set when the ethers provider is created this._provider = null; // set when automining is enabled this.autominer = null; } get cid() { return this.config.chainwebChainId; } get url() { return ''; } get port() { const url = new URL(this.url); return url.port ? parseInt(url.port, 10) : 8454; } async getBlockNumber() { // this.provider.getBlockNumber() is lagging. Maybe it caches internally or // there's a race in the implementation? // return await this.provider.getBlockNumber() return parseInt(await this.provider.send('eth_blockNumber', []), 16); } async makeBlock() { if (this.provider === null) { throw new Error('Provider is not initialized'); } return await this.provider.send('evm_mine', []); } async mineRequest() { await lock.acquire('mine', async () => { this.logger.info(`mining requested`); await this.mine(); }); } async mine() { if (this.adjacents === null) { throw new Error('Chain is not part of a network'); } const cn = await this.getBlockNumber(); this.logger.info(`current height is ${cn}`); for (const a of this.adjacents) { const an = await a.getBlockNumber(); if (an < cn) { await a.mine(); } } this.logger.info(`make new block`); await this.makeBlock(); } async hasPending() { const ps = await this.provider.send('eth_getBlockTransactionCountByNumber', ['pending']); return ps > 0; } async runPending() { const pending = await this.hasPending(); if (pending) { await this.mineRequest(); } } async initializeCidContract() { await this.provider.send('hardhat_setCode', [ network_contracts_js_1.CHAIN_ID_ADDRESS, network_contracts_js_1.CHAIN_ID_BYTE_CODE, ]); const hex = '0x' + this.cid.toString(16).padStart(64, '0'); await this.provider.send('hardhat_setStorageAt', [ network_contracts_js_1.CHAIN_ID_ADDRESS, '0x0', hex, ]); } async initializeVerificationPrecompile() { await this.provider.send('hardhat_setCode', [ network_contracts_js_1.VERIFY_ADDRESS, network_contracts_js_1.VERIFY_BYTE_CODE, ]); } async enableAutomine() { if (!this.autominer) { this.autominer = setInterval(() => this.runPending(), 100); this.logger.info(`Automine enabled`); } } async disableAutomine() { if (this.autominer) { clearInterval(this.autominer); this.autominer = null; this.logger.info(`Automine disabled`); } } async start() { // start hardhat network // await this.startHardhatNetwork(); // create provider try { this._provider = await (0, create_hardhat_provider_js_1.createHardhatProvider)(this.config, this.logger); await this._provider.send('eth_accounts', []); } catch (e) { console.error(e); } // initialize system contracts await this.initializeCidContract(); await this.initializeVerificationPrecompile(); // setup automining await this.provider.send('evm_setAutomine', [false]); await this.enableAutomine(); } async stop() { this.disableAutomine(); this._provider = null; } } exports.Chain = Chain; //# sourceMappingURL=chain.js.map